From 48dc5c96b62692de9508778df2db3c948ada74b3 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 16 Sep 2021 02:47:42 +0900 Subject: [PATCH] PyStrKind --- benches/microbenchmarks.rs | 2 +- derive/src/pymodule.rs | 4 +- src/lib.rs | 2 +- vm/src/builtins/code.rs | 4 +- vm/src/builtins/dict.rs | 6 +- vm/src/builtins/function.rs | 2 +- vm/src/builtins/make_module.rs | 6 +- vm/src/builtins/pystr.rs | 403 ++++++++++++++++++++------------- vm/src/builtins/pysuper.rs | 2 +- vm/src/builtins/pytype.rs | 6 +- vm/src/builtins/set.rs | 6 +- vm/src/codecs.rs | 2 +- vm/src/dictdatatype.rs | 10 +- vm/src/format.rs | 4 +- vm/src/frame.rs | 6 +- vm/src/import.rs | 4 +- vm/src/macros.rs | 2 +- vm/src/py_io.rs | 4 +- vm/src/py_serde.rs | 2 +- vm/src/pyobject.rs | 14 +- vm/src/stdlib/ast.rs | 4 +- vm/src/stdlib/ast/gen.rs | 232 +++++++++---------- vm/src/stdlib/codecs.rs | 4 +- vm/src/stdlib/csv.rs | 2 +- vm/src/stdlib/dis.rs | 8 +- vm/src/stdlib/errno.rs | 2 +- vm/src/stdlib/io.rs | 11 +- vm/src/stdlib/keyword.rs | 2 +- vm/src/stdlib/os.rs | 8 +- vm/src/stdlib/pwd.rs | 4 +- vm/src/stdlib/pyexpat.rs | 2 +- vm/src/stdlib/re.rs | 12 +- vm/src/stdlib/scproxy.rs | 2 +- vm/src/stdlib/socket.rs | 12 +- vm/src/stdlib/sre.rs | 6 +- vm/src/stdlib/ssl.rs | 52 +++-- vm/src/stdlib/string.rs | 2 +- vm/src/stdlib/symtable.rs | 4 +- vm/src/stdlib/termios.rs | 2 +- vm/src/stdlib/time.rs | 4 +- vm/src/stdlib/unicodedata.rs | 4 +- vm/src/stdlib/winreg.rs | 4 +- vm/src/sysmodule.rs | 62 ++--- vm/src/vm.rs | 17 +- wasm/lib/src/browser_module.rs | 2 +- wasm/lib/src/vm_class.rs | 2 +- 46 files changed, 536 insertions(+), 421 deletions(-) diff --git a/benches/microbenchmarks.rs b/benches/microbenchmarks.rs index 3933fd09f9..b3090126d9 100644 --- a/benches/microbenchmarks.rs +++ b/benches/microbenchmarks.rs @@ -132,7 +132,7 @@ fn bench_rustpy_code(group: &mut BenchmarkGroup, bench: &MicroBenchmar if let Some(idx) = iterations { scope .locals - .set_item(vm.ctx.new_str("ITERATIONS"), vm.ctx.new_int(idx), vm) + .set_item(vm.ctx.new_ascii_str(b"ITERATIONS"), vm.ctx.new_int(idx), vm) .expect("Error adding ITERATIONS local variable"); } let setup_result = vm.run_code_obj(setup_code.clone(), scope.clone()); diff --git a/derive/src/pymodule.rs b/derive/src/pymodule.rs index dbb8c6146d..e367c10a89 100644 --- a/derive/src/pymodule.rs +++ b/derive/src/pymodule.rs @@ -268,7 +268,7 @@ impl ModuleItem for FunctionItem { vm.ctx.make_funcdef(#py_name, #ident) #doc .into_function() - .with_module(vm.ctx.new_str(#module.to_owned())) + .with_module(vm.ctx.new_utf8_str(#module.to_owned())) .build(&vm.ctx) ); quote! { @@ -324,7 +324,7 @@ impl ModuleItem for ClassItem { ); let item = quote! { let new_class = #new_class; - new_class.set_str_attr("__module__", vm.ctx.new_str(#module_name)); + new_class.set_str_attr("__module__", vm.ctx.new_utf8_str(#module_name)); vm.__module_set_attr(&module, #py_name, new_class).unwrap(); }; diff --git a/src/lib.rs b/src/lib.rs index 56016a3204..16a64f636c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -588,7 +588,7 @@ fn _run_string(vm: &VirtualMachine, scope: Scope, source: &str, source_path: Str // trace!("Code object: {:?}", code_obj.borrow()); scope .globals - .set_item("__file__", vm.ctx.new_str(source_path), vm)?; + .set_item("__file__", vm.ctx.new_utf8_str(source_path), vm)?; vm.run_code_obj(code_obj, scope) } diff --git a/vm/src/builtins/code.rs b/vm/src/builtins/code.rs index f489b62468..c19f61148d 100644 --- a/vm/src/builtins/code.rs +++ b/vm/src/builtins/code.rs @@ -88,7 +88,7 @@ impl ConstantBag for PyObjBag<'_> { bytecode::ConstantData::Str { value } if value.len() <= 20 => { vm.intern_string(value).into_object() } - bytecode::ConstantData::Str { value } => vm.ctx.new_str(value), + bytecode::ConstantData::Str { value } => vm.ctx.new_utf8_str(value), bytecode::ConstantData::Bytes { value } => ctx.new_bytes(value.to_vec()), bytecode::ConstantData::Boolean { value } => ctx.new_bool(value), bytecode::ConstantData::Code { code } => { @@ -116,7 +116,7 @@ impl ConstantBag for PyObjBag<'_> { bytecode::BorrowedConstant::Str { value } if value.len() <= 20 => { vm.intern_string(value).into_object() } - bytecode::BorrowedConstant::Str { value } => vm.ctx.new_str(value), + bytecode::BorrowedConstant::Str { value } => vm.ctx.new_utf8_str(value), bytecode::BorrowedConstant::Bytes { value } => ctx.new_bytes(value.to_vec()), bytecode::BorrowedConstant::Boolean { value } => ctx.new_bool(value), bytecode::BorrowedConstant::Code { code } => { diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index c98b9fd3cb..535980bd42 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -113,7 +113,7 @@ impl PyDict { } for (key, value) in kwargs.into_iter() { - dict.insert(vm, vm.ctx.new_str(key), value)?; + dict.insert(vm, vm.ctx.new_utf8_str(key), value)?; } Ok(()) } @@ -364,7 +364,7 @@ impl PyDict { if let Some((key, value)) = self.entries.pop_back() { Ok(vm.ctx.new_tuple(vec![key, value])) } else { - let err_msg = vm.ctx.new_str("popitem(): dictionary is empty"); + let err_msg = vm.ctx.new_ascii_str(b"popitem(): dictionary is empty"); Err(vm.new_key_error(err_msg)) } } @@ -373,7 +373,7 @@ impl PyDict { let dict = DictContentType::default(); for (key, value) in attrs { - dict.insert(vm, vm.ctx.new_str(key), value)?; + dict.insert(vm, vm.ctx.new_utf8_str(key), value)?; } Ok(PyDict { entries: dict }) diff --git a/vm/src/builtins/function.rs b/vm/src/builtins/function.rs index 0fcd84f93e..b24cb8faf6 100644 --- a/vm/src/builtins/function.rs +++ b/vm/src/builtins/function.rs @@ -545,7 +545,7 @@ impl PyBoundMethod { // is the only instance of `builtin_function_or_method_type`. let obj_name = vm.get_attribute_opt(self.object.clone(), "__qualname__")?; let obj_name: Option = obj_name.and_then(|o| o.downcast().ok()); - return Ok(vm.ctx.new_str(format!( + return Ok(vm.ctx.new_utf8_str(format!( "{}.__new__", obj_name.as_ref().map_or("?", |s| s.as_str()) ))); diff --git a/vm/src/builtins/make_module.rs b/vm/src/builtins/make_module.rs index 9496d09a7c..128557e12b 100644 --- a/vm/src/builtins/make_module.rs +++ b/vm/src/builtins/make_module.rs @@ -382,7 +382,7 @@ mod decl { let prompt = prompt.as_ref().map_or("", |s| s.as_str()); let mut readline = Readline::new(()); match readline.readline(prompt) { - ReadlineResult::Line(s) => Ok(vm.ctx.new_str(s)), + ReadlineResult::Line(s) => Ok(vm.ctx.new_utf8_str(s)), ReadlineResult::Eof => { Err(vm.new_exception_empty(vm.ctx.exceptions.eof_error.clone())) } @@ -535,7 +535,7 @@ mod decl { format!("0o{:o}", n) }; - Ok(vm.ctx.new_str(s)) + Ok(vm.ctx.new_utf8_str(s)) } #[pyfunction] @@ -812,7 +812,7 @@ mod decl { vm: &VirtualMachine, ) -> PyResult { let name = qualified_name.as_str().split('.').next_back().unwrap(); - let name_obj = vm.ctx.new_str(name); + let name_obj = vm.ctx.new_utf8_str(name); let mut metaclass = if let Some(metaclass) = kwargs.pop_kwarg("metaclass") { PyTypeRef::try_from_object(vm, metaclass)? diff --git a/vm/src/builtins/pystr.rs b/vm/src/builtins/pystr.rs index 2845fe4f0e..308b213ef0 100644 --- a/vm/src/builtins/pystr.rs +++ b/vm/src/builtins/pystr.rs @@ -1,16 +1,3 @@ -use std::mem::size_of; -use std::ops::Range; -use std::string::ToString; -use std::{char, ffi, fmt}; - -use crossbeam_utils::atomic::AtomicCell; -use itertools::Itertools; -use num_traits::ToPrimitive; -use unic_ucd_bidi::BidiClass; -use unic_ucd_category::GeneralCategory; -use unic_ucd_ident::{is_xid_continue, is_xid_start}; -use unicode_casing::CharExt; - use super::bytes::PyBytesRef; use super::dict::PyDict; use super::int::{try_to_primitive, PyInt, PyIntRef}; @@ -31,8 +18,28 @@ use crate::{ IdProtocol, IntoPyObject, ItemProtocol, PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryIntoRef, TypeProtocol, }; +use bstr::ByteSlice; +use crossbeam_utils::atomic::AtomicCell; +use itertools::Itertools; +use num_traits::ToPrimitive; use rustpython_common::atomic::{self, PyAtomic, Radium}; use rustpython_common::hash; +use std::mem::size_of; +use std::ops::Range; +use std::string::ToString; +use std::{char, ffi, fmt}; +use unic_ucd_bidi::BidiClass; +use unic_ucd_category::GeneralCategory; +use unic_ucd_ident::{is_xid_continue, is_xid_start}; +use unicode_casing::CharExt; + +/// Utf8 + state.ascii (+ PyUnicode_Kind in future) +#[derive(Debug)] +pub(crate) enum PyStrKind { + Ascii, + // uses usize::MAX as a sentinel for "uncomputed" + Utf8(PyAtomic), +} /// str(object='') -> str /// str(bytes_or_buffer[, encoding[, errors]]) -> str @@ -47,15 +54,20 @@ use rustpython_common::hash; #[pyclass(module = false, name = "str")] #[derive(Debug)] pub struct PyStr { - value: Box, + bytes: Box<[u8]>, + kind: PyStrKind, hash: PyAtomic, - // uses usize::MAX as a sentinel for "uncomputed" - char_len: PyAtomic, } impl AsRef for PyStr { fn as_ref(&self) -> &str { - &self.value + self.as_str() + } +} + +impl AsRef for PyStrRef { + fn as_ref(&self) -> &str { + self.as_str() } } @@ -67,9 +79,12 @@ where s.as_ref().to_owned().into() } } -impl AsRef for PyStrRef { - fn as_ref(&self) -> &str { - &self.value +impl From<(&T, PyStrKind)> for PyStr +where + T: AsRef<[u8]> + ?Sized, +{ + fn from((s, k): (&T, PyStrKind)) -> PyStr { + (s.as_ref().to_owned().into_boxed_slice(), k).into() } } @@ -82,14 +97,44 @@ impl From for PyStr { impl From> for PyStr { #[inline] fn from(value: Box) -> PyStr { - PyStr { - value, - hash: Radium::new(hash::SENTINEL), - char_len: Radium::new(usize::MAX), + // doing the check is ~10x faster for ascii, and is actually only 2% slower worst case for + // non-ascii; see https://github.com/RustPython/RustPython/pull/2586#issuecomment-844611532 + let is_ascii = value.is_ascii(); + let bytes = unsafe { Box::from_raw(Box::into_raw(value) as _) }; + if is_ascii { + Self { + bytes, + kind: PyStrKind::Ascii, + hash: Radium::new(hash::SENTINEL), + } + } else { + Self { + bytes, + kind: PyStrKind::Utf8(Radium::new(usize::MAX)), + hash: Radium::new(hash::SENTINEL), + } } } } +impl From<(Vec, PyStrKind)> for PyStr { + fn from((s, kind): (Vec, PyStrKind)) -> PyStr { + (s.into_boxed_slice(), kind).into() + } +} + +impl From<(Box<[u8]>, PyStrKind)> for PyStr { + fn from((bytes, kind): (Box<[u8]>, PyStrKind)) -> PyStr { + let s = Self { + bytes, + kind, + hash: Radium::new(hash::SENTINEL), + }; + debug_assert!(matches!(s.kind, PyStrKind::Ascii) || !s.as_str().is_ascii()); + s + } +} + pub type PyStrRef = PyRef; impl fmt::Display for PyStr { @@ -161,7 +206,7 @@ impl PyStrIterator { fn reduce(&self, vm: &VirtualMachine) -> PyResult { let iter = vm.get_attribute(vm.builtins.clone(), "iter")?; Ok(vm.ctx.new_tuple(match self.status.load() { - Exhausted => vec![iter, vm.ctx.new_tuple(vec![vm.ctx.new_str("")])], + Exhausted => vec![iter, vm.ctx.new_tuple(vec![vm.ctx.new_utf8_str("")])], Active => vec![ iter, vm.ctx.new_tuple(vec![self.string.clone().into_object()]), @@ -177,7 +222,7 @@ impl PyIter for PyStrIterator { if let Exhausted = zelf.status.load() { return Err(vm.new_stop_iteration()); } - let value = &*zelf.string.value; + let value = &*zelf.string.as_str(); let mut start = zelf.position.load(atomic::Ordering::SeqCst); loop { if start == value.len() { @@ -246,7 +291,7 @@ impl PyStr { #[pymethod(magic)] fn add(zelf: PyRef, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if let Some(other) = other.payload::() { - Ok(vm.ctx.new_str(zelf.value.py_add(other.as_ref()))) + Ok(vm.ctx.new_utf8_str(zelf.as_str().py_add(other.as_ref()))) } else if let Some(radd) = vm.get_method(other.clone(), "__radd__") { // hack to get around not distinguishing number add from seq concat vm.invoke(&radd?, (zelf,)) @@ -260,12 +305,12 @@ impl PyStr { #[pymethod(magic)] fn bool(&self) -> bool { - !self.value.is_empty() + !self.as_str().is_empty() } #[pymethod(magic)] fn contains(&self, needle: PyStrRef) -> bool { - self.value.contains(needle.as_str()) + self.as_str().contains(needle.as_str()) } #[pymethod(magic)] @@ -274,7 +319,7 @@ impl PyStr { Either::A(ch) => ch.to_string(), Either::B(s) => s, }; - Ok(vm.ctx.new_str(s)) + Ok(vm.ctx.new_utf8_str(s)) } #[inline] @@ -294,44 +339,52 @@ impl PyStr { } pub fn as_str(&self) -> &str { - &self.value + unsafe { std::str::from_utf8_unchecked(&self.bytes) } } #[inline] pub fn byte_len(&self) -> usize { - self.value.len() + self.bytes.len() } #[inline] pub fn is_empty(&self) -> bool { - self.value.is_empty() + self.bytes.is_empty() } #[pymethod(name = "__len__")] #[inline] pub fn char_len(&self) -> usize { - match self.char_len.load(atomic::Ordering::Relaxed) { - usize::MAX => self._compute_char_len(), - len => len, + match self.kind { + PyStrKind::Ascii => self.bytes.len(), + PyStrKind::Utf8(ref len) => match len.load(atomic::Ordering::Relaxed) { + usize::MAX => self._compute_char_len(), + len => len, + }, } } #[cold] fn _compute_char_len(&self) -> usize { - // doing the check is ~10x faster for ascii, and is actually only 2% slower worst case for - // non-ascii; see https://github.com/RustPython/RustPython/pull/2586#issuecomment-844611532 - let len = if self.value.is_ascii() { - self.value.len() - } else { - self.value.chars().count() - }; - // len cannot be usize::MAX, since vec.capacity() < isize::MAX - self.char_len.store(len, atomic::Ordering::Relaxed); - len + match self.kind { + PyStrKind::Utf8(ref char_len) => { + let len = self.as_str().chars().count(); + // len cannot be usize::MAX, since vec.capacity() < isize::MAX + char_len.store(len, atomic::Ordering::Relaxed); + len + } + _ => unsafe { + debug_assert!(false); // invalid for non-utf8 strings + std::hint::unreachable_unchecked() + }, + } } #[pymethod(name = "isascii")] #[inline(always)] pub fn is_ascii(&self) -> bool { - self.char_len() == self.byte_len() + match self.kind { + PyStrKind::Ascii => true, + PyStrKind::Utf8(_) => false, + } } pub fn to_cstring(&self, vm: &VirtualMachine) -> PyResult { @@ -340,7 +393,7 @@ impl PyStr { #[pymethod(magic)] fn sizeof(&self) -> usize { - size_of::() + self.as_str().len() * size_of::() + size_of::() + self.byte_len() * size_of::() } #[pymethod(name = "__rmul__")] @@ -355,7 +408,7 @@ impl PyStr { } // todo: map err to overflow. vm.check_repeat_or_memory_error(zelf.len(), value) - .map(|value| Self::from(zelf.value.repeat(value)).into_ref(vm)) + .map(|value| Self::from(zelf.as_str().repeat(value)).into_ref(vm)) // see issue 45044 on b.p.o. .map_err(|_| vm.new_overflow_error("repeated bytes are too long".to_owned())) } @@ -367,13 +420,13 @@ impl PyStr { #[pymethod(magic)] pub(crate) fn repr(&self, vm: &VirtualMachine) -> PyResult { - let in_len = self.value.len(); + let in_len = self.byte_len(); let mut out_len = 0usize; // let mut max = 127; let mut squote = 0; let mut dquote = 0; - for ch in self.value.chars() { + for ch in self.as_str().chars() { let incr = match ch { '\'' => { squote += 1; @@ -415,7 +468,7 @@ impl PyStr { if unchanged { repr.push_str(self.as_str()); } else { - for ch in self.value.chars() { + for ch in self.as_str().chars() { use std::fmt::Write; match ch { '\n' => repr.push_str("\\n"), @@ -455,7 +508,10 @@ impl PyStr { #[pymethod] fn lower(&self) -> String { - self.value.to_lowercase() + match self.kind { + PyStrKind::Ascii => self.as_str().to_ascii_lowercase(), + PyStrKind::Utf8(_) => self.as_str().to_lowercase(), + } } // casefold is much more aggressive than lower @@ -466,12 +522,15 @@ impl PyStr { #[pymethod] fn upper(&self) -> String { - self.value.to_uppercase() + match self.kind { + PyStrKind::Ascii => self.as_str().to_ascii_uppercase(), + PyStrKind::Utf8(_) => self.as_str().to_uppercase(), + } } #[pymethod] fn capitalize(&self) -> String { - let mut chars = self.value.chars(); + let mut chars = self.as_str().chars(); if let Some(first_char) = chars.next() { format!( "{}{}", @@ -485,24 +544,46 @@ impl PyStr { #[pymethod] fn split(&self, args: SplitArgs, vm: &VirtualMachine) -> PyResult { - let elements = self.value.py_split( - args, - vm, - |v, s, vm| v.split(s).map(|s| vm.ctx.new_str(s)).collect(), - |v, s, n, vm| v.splitn(n, s).map(|s| vm.ctx.new_str(s)).collect(), - |v, n, vm| v.py_split_whitespace(n, |s| vm.ctx.new_str(s)), - )?; + let elements = match self.kind { + PyStrKind::Ascii => self.as_str().py_split( + args, + vm, + |v, s, vm| { + v.as_bytes() + .split_str(s) + .map(|s| vm.ctx.new_ascii_str(s)) + .collect() + }, + |v, s, n, vm| { + v.as_bytes() + .splitn_str(n, s) + .map(|s| vm.ctx.new_ascii_str(s)) + .collect() + }, + |v, n, vm| { + v.as_bytes() + .py_split_whitespace(n, |s| vm.ctx.new_ascii_str(s)) + }, + ), + PyStrKind::Utf8(_) => self.as_str().py_split( + args, + vm, + |v, s, vm| v.split(s).map(|s| vm.ctx.new_utf8_str(s)).collect(), + |v, s, n, vm| v.splitn(n, s).map(|s| vm.ctx.new_utf8_str(s)).collect(), + |v, n, vm| v.py_split_whitespace(n, |s| vm.ctx.new_utf8_str(s)), + ), + }?; Ok(vm.ctx.new_list(elements)) } #[pymethod] fn rsplit(&self, args: SplitArgs, vm: &VirtualMachine) -> PyResult { - let mut elements = self.value.py_split( + let mut elements = self.as_str().py_split( args, vm, - |v, s, vm| v.rsplit(s).map(|s| vm.ctx.new_str(s)).collect(), - |v, s, n, vm| v.rsplitn(n, s).map(|s| vm.ctx.new_str(s)).collect(), - |v, n, vm| v.py_rsplit_whitespace(n, |s| vm.ctx.new_str(s)), + |v, s, vm| v.rsplit(s).map(|s| vm.ctx.new_utf8_str(s)).collect(), + |v, s, n, vm| v.rsplitn(n, s).map(|s| vm.ctx.new_utf8_str(s)).collect(), + |v, n, vm| v.py_rsplit_whitespace(n, |s| vm.ctx.new_utf8_str(s)), )?; // Unlike Python rsplit, Rust rsplitn returns an iterator that // starts from the end of the string. @@ -512,7 +593,7 @@ impl PyStr { #[pymethod] fn strip(&self, chars: OptionalOption) -> String { - self.value + self.as_str() .py_strip( chars, |s, chars| s.trim_matches(|c| chars.contains(c)), @@ -523,7 +604,7 @@ impl PyStr { #[pymethod] fn lstrip(&self, chars: OptionalOption) -> String { - self.value + self.as_str() .py_strip( chars, |s, chars| s.trim_start_matches(|c| chars.contains(c)), @@ -534,7 +615,7 @@ impl PyStr { #[pymethod] fn rstrip(&self, chars: OptionalOption) -> String { - self.value + self.as_str() .py_strip( chars, |s, chars| s.trim_end_matches(|c| chars.contains(c)), @@ -545,7 +626,7 @@ impl PyStr { #[pymethod] fn endswith(&self, args: anystr::StartsEndsWithArgs, vm: &VirtualMachine) -> PyResult { - self.value.py_startsendswith( + self.as_str().py_startsendswith( args, "endswith", "str", @@ -556,7 +637,7 @@ impl PyStr { #[pymethod] fn startswith(&self, args: anystr::StartsEndsWithArgs, vm: &VirtualMachine) -> PyResult { - self.value.py_startsendswith( + self.as_str().py_startsendswith( args, "startswith", "str", @@ -565,42 +646,38 @@ impl PyStr { ) } - /// removeprefix($self, prefix, /) - /// - /// /// Return a str with the given prefix string removed if present. /// /// If the string starts with the prefix string, return string[len(prefix):] /// Otherwise, return a copy of the original string. #[pymethod] fn removeprefix(&self, pref: PyStrRef) -> String { - self.value - .py_removeprefix(pref.as_str(), pref.value.len(), |s, p| s.starts_with(p)) + self.as_str() + .py_removeprefix(pref.as_str(), pref.byte_len(), |s, p| s.starts_with(p)) .to_owned() } - /// removesuffix(self, prefix, /) - /// - /// /// Return a str with the given suffix string removed if present. /// /// If the string ends with the suffix string, return string[:len(suffix)] /// Otherwise, return a copy of the original string. #[pymethod] fn removesuffix(&self, suff: PyStrRef) -> String { - self.value - .py_removesuffix(suff.as_str(), suff.value.len(), |s, p| s.ends_with(p)) + self.as_str() + .py_removesuffix(suff.as_str(), suff.byte_len(), |s, p| s.ends_with(p)) .to_owned() } #[pymethod] fn isalnum(&self) -> bool { - !self.value.is_empty() && self.value.chars().all(char::is_alphanumeric) + let s = self.as_str(); + !s.is_empty() && s.chars().all(char::is_alphanumeric) } #[pymethod] fn isnumeric(&self) -> bool { - !self.value.is_empty() && self.value.chars().all(char::is_numeric) + let s = self.as_str(); + !s.is_empty() && s.chars().all(char::is_numeric) } #[pymethod] @@ -609,23 +686,22 @@ impl PyStr { let valid_unicodes: [u16; 10] = [ 0x2070, 0x00B9, 0x00B2, 0x00B3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, ]; - - !self.value.is_empty() - && self - .value - .chars() + let s = self.as_str(); + !s.is_empty() + && s.chars() .filter(|c| !c.is_digit(10)) .all(|c| valid_unicodes.contains(&(c as u16))) } #[pymethod] fn isdecimal(&self) -> bool { - !self.value.is_empty() && self.value.chars().all(|c| c.is_ascii_digit()) + let s = self.as_str(); + !s.is_empty() && s.chars().all(|c| c.is_ascii_digit()) } #[pymethod(name = "__mod__")] fn modulo(&self, values: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let formatted = self.value.py_cformat(values, vm)?; + let formatted = self.as_str().py_cformat(values, vm)?; Ok(formatted) } @@ -636,10 +712,9 @@ impl PyStr { #[pymethod] fn format(&self, args: FuncArgs, vm: &VirtualMachine) -> PyResult { - match FormatString::from_str(self.as_str()) { - Ok(format_string) => format_string.format(&args, vm), - Err(err) => Err(err.into_pyexception(vm)), - } + let format_string = + FormatString::from_str(self.as_str()).map_err(|e| e.into_pyexception(vm))?; + format_string.format(&args, vm) } /// S.format_map(mapping) -> str @@ -668,9 +743,9 @@ impl PyStr { /// uppercase character and the remaining characters are lowercase. #[pymethod] fn title(&self) -> String { - let mut title = String::with_capacity(self.value.len()); + let mut title = String::with_capacity(self.bytes.len()); let mut previous_is_cased = false; - for c in self.value.chars() { + for c in self.as_str().chars() { if c.is_lowercase() { if !previous_is_cased { title.extend(c.to_titlecase()); @@ -695,8 +770,8 @@ impl PyStr { #[pymethod] fn swapcase(&self) -> String { - let mut swapped_str = String::with_capacity(self.value.len()); - for c in self.value.chars() { + let mut swapped_str = String::with_capacity(self.bytes.len()); + for c in self.as_str().chars() { // to_uppercase returns an iterator, to_ascii_uppercase returns the char if c.is_lowercase() { swapped_str.push(c.to_ascii_uppercase()); @@ -711,21 +786,23 @@ impl PyStr { #[pymethod] fn isalpha(&self) -> bool { - !self.value.is_empty() && self.value.chars().all(char::is_alphabetic) + let s = self.as_str(); + !s.is_empty() && s.chars().all(char::is_alphabetic) } #[pymethod] fn replace(&self, old: PyStrRef, new: PyStrRef, count: OptionalArg) -> String { + let s = self.as_str(); match count { OptionalArg::Present(maxcount) if maxcount >= 0 => { - if maxcount == 0 || self.value.is_empty() { + if maxcount == 0 || s.is_empty() { // nothing to do; return the original bytes - return String::from(self.as_str()); + s.into() + } else { + s.replacen(old.as_str(), new.as_str(), maxcount as usize) } - self.value - .replacen(old.as_str(), new.as_str(), maxcount as usize) } - _ => self.value.replace(old.as_str(), new.as_str()), + _ => s.replace(old.as_str(), new.as_str()), } } @@ -746,18 +823,18 @@ impl PyStr { /// * Zs (Separator, Space) other than ASCII space('\x20'). #[pymethod] fn isprintable(&self) -> bool { - self.value + self.as_str() .chars() .all(|c| c == '\u{0020}' || char_is_printable(c)) } #[pymethod] fn isspace(&self) -> bool { - if self.value.is_empty() { + if self.bytes.is_empty() { return false; } use unic_ucd_bidi::bidi_class::abbr_names::*; - self.value.chars().all(|c| { + self.as_str().chars().all(|c| { GeneralCategory::of(c) == GeneralCategory::SpaceSeparator || matches!(BidiClass::of(c), WS | B | S) }) @@ -766,25 +843,37 @@ impl PyStr { // Return true if all cased characters in the string are lowercase and there is at least one cased character, false otherwise. #[pymethod] fn islower(&self) -> bool { - self.value.py_iscase(char::is_lowercase, char::is_uppercase) + match self.kind { + PyStrKind::Ascii => self.bytes.py_iscase(char::is_lowercase, char::is_uppercase), + PyStrKind::Utf8(_) => self + .as_str() + .py_iscase(char::is_lowercase, char::is_uppercase), + } } // Return true if all cased characters in the string are uppercase and there is at least one cased character, false otherwise. #[pymethod] fn isupper(&self) -> bool { - self.value.py_iscase(char::is_uppercase, char::is_lowercase) + match self.kind { + PyStrKind::Ascii => self.bytes.py_iscase(char::is_uppercase, char::is_lowercase), + PyStrKind::Utf8(_) => self + .as_str() + .py_iscase(char::is_uppercase, char::is_lowercase), + } } #[pymethod] fn splitlines(&self, args: anystr::SplitLinesArgs, vm: &VirtualMachine) -> PyObjectRef { - vm.ctx - .new_list(self.value.py_splitlines(args, |s| vm.ctx.new_str(s))) + vm.ctx.new_list( + self.as_str() + .py_splitlines(args, |s| vm.ctx.new_utf8_str(s)), + ) } #[pymethod] fn join(&self, iterable: PyIterable, vm: &VirtualMachine) -> PyResult { let iter = iterable.iter(vm)?; - self.value.py_join(iter) + self.as_str().py_join(iter) } // FIXME: two traversals of str is expensive @@ -799,7 +888,7 @@ impl PyStr { F: Fn(&str, &str) -> Option, { let (sub, range) = args.get_value(self.len()); - self.value.py_find(sub.as_str(), range, find) + self.as_str().py_find(sub.as_str(), range, find) } #[pymethod] @@ -828,33 +917,37 @@ impl PyStr { #[pymethod] fn partition(&self, sep: PyStrRef, vm: &VirtualMachine) -> PyResult { - let (front, has_mid, back) = - self.value - .py_partition(sep.as_str(), || self.value.splitn(2, sep.as_str()), vm)?; + let (front, has_mid, back) = self.as_str().py_partition( + sep.as_str(), + || self.as_str().splitn(2, sep.as_str()), + vm, + )?; Ok(vm.ctx.new_tuple(vec![ - vm.ctx.new_str(front), + vm.ctx.new_utf8_str(front), if has_mid { sep.into_object() } else { - vm.ctx.new_str("") + vm.ctx.new_ascii_str(b"") }, - vm.ctx.new_str(back), + vm.ctx.new_utf8_str(back), ])) } #[pymethod] fn rpartition(&self, sep: PyStrRef, vm: &VirtualMachine) -> PyResult { - let (back, has_mid, front) = - self.value - .py_partition(sep.as_str(), || self.value.rsplitn(2, sep.as_str()), vm)?; + let (back, has_mid, front) = self.as_str().py_partition( + sep.as_str(), + || self.as_str().rsplitn(2, sep.as_str()), + vm, + )?; Ok(vm.ctx.new_tuple(vec![ - vm.ctx.new_str(front), + vm.ctx.new_utf8_str(front), if has_mid { sep.into_object() } else { - vm.ctx.new_str("") + vm.ctx.new_ascii_str(b"") }, - vm.ctx.new_str(back), + vm.ctx.new_utf8_str(back), ])) } @@ -862,13 +955,13 @@ impl PyStr { /// empty, `false` otherwise. #[pymethod] fn istitle(&self) -> bool { - if self.value.is_empty() { + if self.as_str().is_empty() { return false; } let mut cased = false; let mut previous_is_cased = false; - for c in self.value.chars() { + for c in self.as_str().chars() { if c.is_uppercase() || c.is_titlecase() { if previous_is_cased { return false; @@ -891,14 +984,14 @@ impl PyStr { #[pymethod] fn count(&self, args: FindArgs) -> usize { let (needle, range) = args.get_value(self.len()); - self.value + self.as_str() .py_count(needle.as_str(), range, |h, n| h.matches(n).count()) } #[pymethod] fn zfill(&self, width: isize) -> String { - // this is safe-guaranteed because the original self.value is valid utf8 - unsafe { String::from_utf8_unchecked(self.value.py_zfill(width)) } + // this is safe-guaranteed because the original self.as_str() is valid utf8 + unsafe { String::from_utf8_unchecked(self.as_str().py_zfill(width)) } } #[inline] @@ -910,7 +1003,7 @@ impl PyStr { vm: &VirtualMachine, ) -> PyResult { let fillchar = fillchar.map_or(Ok(' '), |ref s| { - s.value.chars().exactly_one().map_err(|_| { + s.as_str().chars().exactly_one().map_err(|_| { vm.new_type_error( "The fill character must be exactly one character long".to_owned(), ) @@ -956,10 +1049,10 @@ impl PyStr { #[pymethod] fn expandtabs(&self, args: anystr::ExpandTabsArgs) -> String { let tab_stop = args.tabsize(); - let mut expanded_str = String::with_capacity(self.value.len()); + let mut expanded_str = String::with_capacity(self.byte_len()); let mut tab_size = tab_stop; let mut col_count = 0usize; - for ch in self.value.chars() { + for ch in self.as_str().chars() { match ch { '\t' => { let num_spaces = tab_size - col_count; @@ -986,7 +1079,7 @@ impl PyStr { #[pymethod] fn isidentifier(&self) -> bool { - let mut chars = self.value.chars(); + let mut chars = self.as_str().chars(); let is_identifier_start = chars.next().map_or(false, |c| c == '_' || is_xid_start(c)); // a string is not an identifier if it has whitespace or starts with a number is_identifier_start && chars.all(is_xid_continue) @@ -1000,7 +1093,7 @@ impl PyStr { })?; let mut translated = String::new(); - for c in self.value.chars() { + for c in self.as_str().chars() { match table.get_item((c as u32).into_pyobject(vm), vm) { Ok(value) => { if let Some(text) = value.payload::() { @@ -1040,7 +1133,7 @@ impl PyStr { match dict_or_str.downcast::() { Ok(from_str) => { if to_str.len() == from_str.len() { - for (c1, c2) in from_str.value.chars().zip(to_str.value.chars()) { + for (c1, c2) in from_str.as_str().chars().zip(to_str.as_str().chars()) { new_dict.set_item( vm.ctx.new_int(c1 as u32), vm.ctx.new_int(c2 as u32), @@ -1048,7 +1141,7 @@ impl PyStr { )?; } if let OptionalArg::Present(none_str) = none_str { - for c in none_str.value.chars() { + for c in none_str.as_str().chars() { new_dict.set_item(vm.ctx.new_int(c as u32), vm.ctx.none(), vm)?; } } @@ -1077,7 +1170,7 @@ impl PyStr { )?; } else if let Some(string) = key.payload::() { if string.len() == 1 { - let num_value = string.value.chars().next().unwrap() as u32; + let num_value = string.as_str().chars().next().unwrap() as u32; new_dict.set_item(num_value.into_pyobject(vm), val, vm)?; } else { return Err(vm.new_value_error( @@ -1174,25 +1267,25 @@ impl PyValue for PyStr { impl IntoPyObject for String { fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - vm.ctx.new_str(self) + vm.ctx.new_utf8_str(self) } } impl IntoPyObject for char { fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - vm.ctx.new_str(self.to_string()) + vm.ctx.new_utf8_str(self.to_string()) } } impl IntoPyObject for &str { fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - vm.ctx.new_str(self) + vm.ctx.new_utf8_str(self) } } impl IntoPyObject for &String { fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - vm.ctx.new_str(self.clone()) + vm.ctx.new_utf8_str(self.clone()) } } @@ -1227,14 +1320,14 @@ impl PySliceableSequence for PyStr { fn do_get(&self, index: usize) -> Self::Item { if self.is_ascii() { - self.value.as_bytes()[index] as char + self.bytes[index] as char } else { - self.value.chars().nth(index).unwrap() + self.as_str().chars().nth(index).unwrap() } } fn do_slice(&self, range: Range) -> Self::Sliced { - let value = &*self.value; + let value = self.as_str(); if self.is_ascii() { value[range].to_owned() } else { @@ -1243,7 +1336,7 @@ impl PySliceableSequence for PyStr { } fn do_slice_reverse(&self, range: Range) -> Self::Sliced { - let value = &*self.value; + let value = self.as_str(); let char_len = self.char_len(); if char_len == self.byte_len() { // this is an ascii string @@ -1265,15 +1358,17 @@ impl PySliceableSequence for PyStr { } fn do_stepped_slice(&self, range: Range, step: usize) -> Self::Sliced { - let value = &*self.value; + let value = self.as_str(); if self.is_ascii() { let v = value.as_bytes()[range] .iter() .copied() .step_by(step) .collect(); - // TODO: from_utf8_unchecked? - String::from_utf8(v).unwrap() + unsafe { + // SAFETY: Any subset of ascii string is a valid utf8 string + String::from_utf8_unchecked(v) + } } else { let mut s = String::with_capacity(2 * ((range.len() / step) + 1)); s.extend( @@ -1288,7 +1383,7 @@ impl PySliceableSequence for PyStr { } fn do_stepped_slice_reverse(&self, range: Range, step: usize) -> Self::Sliced { - let value = &*self.value; + let value = &*self.as_str(); let char_len = self.char_len(); if char_len == self.byte_len() { // this is an ascii string @@ -1397,9 +1492,11 @@ mod tests { fn str_maketrans_and_translate() { Interpreter::default().enter(|vm| { let table = vm.ctx.new_dict(); - table.set_item("a", vm.ctx.new_str("🎅"), &vm).unwrap(); + table.set_item("a", vm.ctx.new_utf8_str("🎅"), &vm).unwrap(); table.set_item("b", vm.ctx.none(), &vm).unwrap(); - table.set_item("c", vm.ctx.new_str("xda"), &vm).unwrap(); + table + .set_item("c", vm.ctx.new_ascii_str(b"xda"), &vm) + .unwrap(); let translated = PyStr::maketrans( table.into_object(), OptionalArg::Missing, @@ -1422,7 +1519,7 @@ mod tests { impl<'s> AnyStrWrapper<'s> for PyStrRef { type Str = str; fn as_ref(&self) -> &str { - &*self.value + &*self.as_str() } } diff --git a/vm/src/builtins/pysuper.rs b/vm/src/builtins/pysuper.rs index 7ecb3a6b02..935edf7fab 100644 --- a/vm/src/builtins/pysuper.rs +++ b/vm/src/builtins/pysuper.rs @@ -211,6 +211,6 @@ pub fn init(context: &PyContext) { super().cmeth(arg)\n"; extend_class!(context, super_type, { - "__doc__" => context.new_str(super_doc), + "__doc__" => context.new_utf8_str(super_doc), }); } diff --git a/vm/src/builtins/pytype.rs b/vm/src/builtins/pytype.rs index 46a4713ee5..955c12aca8 100644 --- a/vm/src/builtins/pytype.rs +++ b/vm/src/builtins/pytype.rs @@ -266,7 +266,7 @@ impl PyType { let attributes: Vec = zelf .get_attributes() .drain() - .map(|(k, _)| vm.ctx.new_str(k)) + .map(|(k, _)| vm.ctx.new_utf8_str(k)) .collect(); PyList::from(attributes) } @@ -326,7 +326,7 @@ impl PyType { Some(found) } }) - .unwrap_or_else(|| vm.ctx.new_str(self.name())) + .unwrap_or_else(|| vm.ctx.new_utf8_str(self.name())) } #[pyproperty(magic)] @@ -344,7 +344,7 @@ impl PyType { Some(found) } }) - .unwrap_or_else(|| vm.ctx.new_str("builtins")) + .unwrap_or_else(|| vm.ctx.new_ascii_str(b"builtins")) } #[pyproperty(magic, setter)] diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index ba7d768cff..0483a52f26 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -232,7 +232,7 @@ impl PySetInner { if let Some((key, _)) = self.content.pop_back() { Ok(key) } else { - let err_msg = vm.ctx.new_str("pop from an empty set"); + let err_msg = vm.ctx.new_ascii_str(b"pop from an empty set"); Err(vm.new_key_error(err_msg)) } } @@ -475,7 +475,7 @@ impl PySet { } else { "set(...)".to_owned() }; - Ok(vm.ctx.new_str(s)) + Ok(vm.ctx.new_utf8_str(s)) } #[pymethod] @@ -743,7 +743,7 @@ impl PyFrozenSet { } else { "frozenset(...)".to_owned() }; - Ok(vm.ctx.new_str(s)) + Ok(vm.ctx.new_utf8_str(s)) } #[pymethod(magic)] diff --git a/vm/src/codecs.rs b/vm/src/codecs.rs index 4045ed819f..86edea55a9 100644 --- a/vm/src/codecs.rs +++ b/vm/src/codecs.rs @@ -367,7 +367,7 @@ fn strict_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult { fn ignore_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(PyObjectRef, usize)> { if is_encode_ish_err(&err, vm) || is_decode_err(&err, vm) { let range = extract_unicode_error_range(&err, vm)?; - Ok((vm.ctx.new_str(""), range.end)) + Ok((vm.ctx.new_ascii_str(b""), range.end)) } else { Err(bad_err_type(err, vm)) } diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index 78c3c2cb19..0dafae1aa8 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -729,7 +729,7 @@ impl DictKey for &str { Ok(pystr.as_str() == *self) } else { // Fall back to PyObjectRef implementation. - let s = vm.ctx.new_str(*self); + let s = vm.ctx.new_utf8_str(*self); s.key_eq(vm, other_key) } } @@ -775,12 +775,12 @@ mod tests { assert_eq!(0, dict.len()); let key1 = vm.ctx.new_bool(true); - let value1 = vm.ctx.new_str("abc"); + let value1 = vm.ctx.new_ascii_str(b"abc"); dict.insert(&vm, key1.clone(), value1.clone()).unwrap(); assert_eq!(1, dict.len()); - let key2 = vm.ctx.new_str("x"); - let value2 = vm.ctx.new_str("def"); + let key2 = vm.ctx.new_ascii_str(b"x"); + let value2 = vm.ctx.new_ascii_str(b"def"); dict.insert(&vm, key2.clone(), value2.clone()).unwrap(); assert_eq!(2, dict.len()); @@ -821,7 +821,7 @@ mod tests { fn check_hash_equivalence(text: &str) { Interpreter::default().enter(|vm| { let value1 = text; - let value2 = vm.ctx.new_str(value1.to_owned()); + let value2 = vm.ctx.new_utf8_str(value1.to_owned()); let hash1 = value1.key_hash(&vm).expect("Hash should not fail."); let hash2 = value2.key_hash(&vm).expect("Hash should not fail."); diff --git a/vm/src/format.rs b/vm/src/format.rs index fc07aa8f38..57ac71c6de 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -870,7 +870,7 @@ impl FormatString { } FieldType::Keyword(keyword) => arguments .get_optional_kwarg(&keyword) - .ok_or_else(|| vm.new_key_error(vm.ctx.new_str(keyword))), + .ok_or_else(|| vm.new_key_error(vm.ctx.new_utf8_str(keyword))), }) } @@ -893,7 +893,7 @@ fn call_object_format( let argument = match preconversion_spec.and_then(FormatPreconversor::from_char) { Some(FormatPreconversor::Str) => vm.to_str(&argument)?.into_object(), Some(FormatPreconversor::Repr) => vm.to_repr(&argument)?.into_object(), - Some(FormatPreconversor::Ascii) => vm.ctx.new_str(builtins::ascii(argument, vm)?), + Some(FormatPreconversor::Ascii) => vm.ctx.new_utf8_str(builtins::ascii(argument, vm)?), Some(FormatPreconversor::Bytes) => vm.call_method(&argument, "decode", ())?, None => argument, }; diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 97436b84bf..bd790f76d6 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -654,7 +654,7 @@ impl ExecutingFrame<'_> { .iter() .map(|pyobj| pyobj.payload::().unwrap().as_ref()) .collect::(); - let str_obj = vm.ctx.new_str(s); + let str_obj = vm.ctx.new_utf8_str(s); self.push_value(str_obj); Ok(None) } @@ -1056,7 +1056,7 @@ impl ExecutingFrame<'_> { let value = match conversion { ConversionFlag::Str => vm.to_str(&value)?.into_object(), ConversionFlag::Repr => vm.to_repr(&value)?.into_object(), - ConversionFlag::Ascii => vm.ctx.new_str(builtins::ascii(value, vm)?), + ConversionFlag::Ascii => vm.ctx.new_utf8_str(builtins::ascii(value, vm)?), ConversionFlag::None => value, }; @@ -1602,7 +1602,7 @@ impl ExecutingFrame<'_> { vm.set_attr(&func_obj, "__doc__", vm.ctx.none())?; let name = qualified_name.as_str().split('.').next_back().unwrap(); - vm.set_attr(&func_obj, "__name__", vm.ctx.new_str(name))?; + vm.set_attr(&func_obj, "__name__", vm.ctx.new_utf8_str(name))?; vm.set_attr(&func_obj, "__qualname__", qualified_name)?; let module = vm.unwrap_or_none(self.globals.get_item_option("__name__", vm)?); vm.set_attr(&func_obj, "__module__", module)?; diff --git a/vm/src/import.rs b/vm/src/import.rs index 465ef299e5..5bc0b2d58b 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -126,9 +126,9 @@ pub fn import_codeobj( set_file_attr: bool, ) -> PyResult { let attrs = vm.ctx.new_dict(); - attrs.set_item("__name__", vm.ctx.new_str(module_name), vm)?; + attrs.set_item("__name__", vm.ctx.new_utf8_str(module_name), vm)?; if set_file_attr { - attrs.set_item("__file__", vm.ctx.new_str(&code_obj.source_path), vm)?; + attrs.set_item("__file__", vm.ctx.new_utf8_str(&code_obj.source_path), vm)?; } let module = vm.new_module(module_name, attrs.clone()); diff --git a/vm/src/macros.rs b/vm/src/macros.rs index f49a4a65a4..94a512efce 100644 --- a/vm/src/macros.rs +++ b/vm/src/macros.rs @@ -228,7 +228,7 @@ macro_rules! named_function { [<$module _ $func>], ) .into_function() - .with_module(ctx.new_str(stringify!($module).to_owned())) + .with_module(ctx.new_utf8_str(stringify!($module).to_owned())) .build(ctx) } }}; diff --git a/vm/src/py_io.rs b/vm/src/py_io.rs index ab8ae8c7d5..f7dd9d134d 100644 --- a/vm/src/py_io.rs +++ b/vm/src/py_io.rs @@ -65,7 +65,7 @@ pub fn file_readline(obj: &PyObjectRef, size: Option, vm: &VirtualMachine let eof_err = || { vm.new_exception( vm.ctx.exceptions.eof_error.clone(), - vec![vm.ctx.new_str("EOF when reading a line".to_owned())], + vec![vm.ctx.new_ascii_str(b"EOF when reading a line")], ) }; let ret = match_class!(match ret { @@ -75,7 +75,7 @@ pub fn file_readline(obj: &PyObjectRef, size: Option, vm: &VirtualMachine return Err(eof_err()); } if let Some(nonl) = sval.strip_suffix('\n') { - vm.ctx.new_str(nonl.to_owned()) + vm.ctx.new_utf8_str(nonl) } else { s.into_object() } diff --git a/vm/src/py_serde.rs b/vm/src/py_serde.rs index 2db7f9f40e..d92b016d26 100644 --- a/vm/src/py_serde.rs +++ b/vm/src/py_serde.rs @@ -177,7 +177,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> { where E: serde::de::Error, { - Ok(self.vm.ctx.new_str(value)) + Ok(self.vm.ctx.new_utf8_str(value)) } fn visit_unit(self) -> Result diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 8760f5ab38..15c92bb162 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -203,13 +203,21 @@ impl PyContext { ) } - pub fn new_str(&self, s: S) -> PyObjectRef + pub fn new_utf8_str(&self, s: S) -> PyObjectRef where S: Into, { PyObject::new(s.into(), self.types.str_type.clone(), None) } + pub fn new_ascii_str(&self, s: &[u8]) -> PyObjectRef { + PyObject::new( + pystr::PyStr::from((s, pystr::PyStrKind::Ascii)), + self.types.str_type.clone(), + None, + ) + } + pub fn new_bytes(&self, data: Vec) -> PyObjectRef { PyObject::new( bytes::PyBytes::from(data), @@ -1102,10 +1110,10 @@ pub trait PyClassImpl: PyClassDef { Self::impl_extend_class(ctx, class); ctx.add_slot_wrappers(class); if let Some(doc) = Self::DOC { - class.set_str_attr("__doc__", ctx.new_str(doc)); + class.set_str_attr("__doc__", ctx.new_utf8_str(doc)); } if let Some(module_name) = Self::MODULE_NAME { - class.set_str_attr("__module__", ctx.new_str(module_name)); + class.set_str_attr("__module__", ctx.new_utf8_str(module_name)); } } diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index 5bdb43fdd5..f867c4b9ab 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -167,7 +167,7 @@ fn node_add_location(node: &PyObjectRef, location: ast::Location, vm: &VirtualMa impl Node for String { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { - vm.ctx.new_str(self) + vm.ctx.new_utf8_str(self) } fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult { @@ -200,7 +200,7 @@ impl Node for ast::Constant { match self { ast::Constant::None => vm.ctx.none(), ast::Constant::Bool(b) => vm.ctx.new_bool(b), - ast::Constant::Str(s) => vm.ctx.new_str(s), + ast::Constant::Str(s) => vm.ctx.new_utf8_str(s), ast::Constant::Bytes(b) => vm.ctx.new_bytes(b), ast::Constant::Int(i) => vm.ctx.new_int(i), ast::Constant::Tuple(t) => vm diff --git a/vm/src/stdlib/ast/gen.rs b/vm/src/stdlib/ast/gen.rs index d865c91d8e..d486c8992c 100644 --- a/vm/src/stdlib/ast/gen.rs +++ b/vm/src/stdlib/ast/gen.rs @@ -8,7 +8,7 @@ struct NodeModule; impl NodeModule { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("body"),ctx.new_str("type_ignores")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"type_ignores")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -18,7 +18,7 @@ struct NodeInteractive; impl NodeInteractive { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("body")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"body")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -28,7 +28,7 @@ struct NodeExpression; impl NodeExpression { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("body")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"body")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -38,7 +38,7 @@ struct NodeFunctionType; impl NodeFunctionType { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("argtypes"),ctx.new_str("returns")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"argtypes"),ctx.new_ascii_str(b"returns")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -48,8 +48,8 @@ struct NodeFunctionDef; impl NodeFunctionDef { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("name"),ctx.new_str("args"),ctx.new_str("body"),ctx.new_str("decorator_list"),ctx.new_str("returns"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"name"),ctx.new_ascii_str(b"args"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"decorator_list"),ctx.new_ascii_str(b"returns"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "AsyncFunctionDef", base = "AstNode")] @@ -58,8 +58,8 @@ struct NodeAsyncFunctionDef; impl NodeAsyncFunctionDef { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("name"),ctx.new_str("args"),ctx.new_str("body"),ctx.new_str("decorator_list"),ctx.new_str("returns"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"name"),ctx.new_ascii_str(b"args"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"decorator_list"),ctx.new_ascii_str(b"returns"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "ClassDef", base = "AstNode")] @@ -68,8 +68,8 @@ struct NodeClassDef; impl NodeClassDef { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("name"),ctx.new_str("bases"),ctx.new_str("keywords"),ctx.new_str("body"),ctx.new_str("decorator_list")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"name"),ctx.new_ascii_str(b"bases"),ctx.new_ascii_str(b"keywords"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"decorator_list")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Return", base = "AstNode")] @@ -78,8 +78,8 @@ struct NodeReturn; impl NodeReturn { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Delete", base = "AstNode")] @@ -88,8 +88,8 @@ struct NodeDelete; impl NodeDelete { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("targets")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"targets")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Assign", base = "AstNode")] @@ -98,8 +98,8 @@ struct NodeAssign; impl NodeAssign { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("targets"),ctx.new_str("value"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"targets"),ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "AugAssign", base = "AstNode")] @@ -108,8 +108,8 @@ struct NodeAugAssign; impl NodeAugAssign { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("target"),ctx.new_str("op"),ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"target"),ctx.new_ascii_str(b"op"),ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "AnnAssign", base = "AstNode")] @@ -118,8 +118,8 @@ struct NodeAnnAssign; impl NodeAnnAssign { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("target"),ctx.new_str("annotation"),ctx.new_str("value"),ctx.new_str("simple")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"target"),ctx.new_ascii_str(b"annotation"),ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"simple")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "For", base = "AstNode")] @@ -128,8 +128,8 @@ struct NodeFor; impl NodeFor { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("target"),ctx.new_str("iter"),ctx.new_str("body"),ctx.new_str("orelse"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"target"),ctx.new_ascii_str(b"iter"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"orelse"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "AsyncFor", base = "AstNode")] @@ -138,8 +138,8 @@ struct NodeAsyncFor; impl NodeAsyncFor { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("target"),ctx.new_str("iter"),ctx.new_str("body"),ctx.new_str("orelse"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"target"),ctx.new_ascii_str(b"iter"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"orelse"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "While", base = "AstNode")] @@ -148,8 +148,8 @@ struct NodeWhile; impl NodeWhile { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("test"),ctx.new_str("body"),ctx.new_str("orelse")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"test"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"orelse")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "If", base = "AstNode")] @@ -158,8 +158,8 @@ struct NodeIf; impl NodeIf { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("test"),ctx.new_str("body"),ctx.new_str("orelse")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"test"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"orelse")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "With", base = "AstNode")] @@ -168,8 +168,8 @@ struct NodeWith; impl NodeWith { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("items"),ctx.new_str("body"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"items"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "AsyncWith", base = "AstNode")] @@ -178,8 +178,8 @@ struct NodeAsyncWith; impl NodeAsyncWith { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("items"),ctx.new_str("body"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"items"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Raise", base = "AstNode")] @@ -188,8 +188,8 @@ struct NodeRaise; impl NodeRaise { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("exc"),ctx.new_str("cause")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"exc"),ctx.new_ascii_str(b"cause")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Try", base = "AstNode")] @@ -198,8 +198,8 @@ struct NodeTry; impl NodeTry { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("body"),ctx.new_str("handlers"),ctx.new_str("orelse"),ctx.new_str("finalbody")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"handlers"),ctx.new_ascii_str(b"orelse"),ctx.new_ascii_str(b"finalbody")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Assert", base = "AstNode")] @@ -208,8 +208,8 @@ struct NodeAssert; impl NodeAssert { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("test"),ctx.new_str("msg")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"test"),ctx.new_ascii_str(b"msg")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Import", base = "AstNode")] @@ -218,8 +218,8 @@ struct NodeImport; impl NodeImport { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("names")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"names")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "ImportFrom", base = "AstNode")] @@ -228,8 +228,8 @@ struct NodeImportFrom; impl NodeImportFrom { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("module"),ctx.new_str("names"),ctx.new_str("level")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"module"),ctx.new_ascii_str(b"names"),ctx.new_ascii_str(b"level")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Global", base = "AstNode")] @@ -238,8 +238,8 @@ struct NodeGlobal; impl NodeGlobal { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("names")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"names")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Nonlocal", base = "AstNode")] @@ -248,8 +248,8 @@ struct NodeNonlocal; impl NodeNonlocal { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("names")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"names")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Expr", base = "AstNode")] @@ -258,8 +258,8 @@ struct NodeExpr; impl NodeExpr { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Pass", base = "AstNode")] @@ -269,7 +269,7 @@ impl NodePass { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { class.set_str_attr("_fields", ctx.new_list(vec![])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Break", base = "AstNode")] @@ -279,7 +279,7 @@ impl NodeBreak { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { class.set_str_attr("_fields", ctx.new_list(vec![])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Continue", base = "AstNode")] @@ -289,7 +289,7 @@ impl NodeContinue { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { class.set_str_attr("_fields", ctx.new_list(vec![])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "BoolOp", base = "AstNode")] @@ -298,8 +298,8 @@ struct NodeBoolOp; impl NodeBoolOp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("op"),ctx.new_str("values")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"op"),ctx.new_ascii_str(b"values")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "NamedExpr", base = "AstNode")] @@ -308,8 +308,8 @@ struct NodeNamedExpr; impl NodeNamedExpr { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("target"),ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"target"),ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "BinOp", base = "AstNode")] @@ -318,8 +318,8 @@ struct NodeBinOp; impl NodeBinOp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("left"),ctx.new_str("op"),ctx.new_str("right")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"left"),ctx.new_ascii_str(b"op"),ctx.new_ascii_str(b"right")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "UnaryOp", base = "AstNode")] @@ -328,8 +328,8 @@ struct NodeUnaryOp; impl NodeUnaryOp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("op"),ctx.new_str("operand")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"op"),ctx.new_ascii_str(b"operand")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Lambda", base = "AstNode")] @@ -338,8 +338,8 @@ struct NodeLambda; impl NodeLambda { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("args"),ctx.new_str("body")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"args"),ctx.new_ascii_str(b"body")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "IfExp", base = "AstNode")] @@ -348,8 +348,8 @@ struct NodeIfExp; impl NodeIfExp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("test"),ctx.new_str("body"),ctx.new_str("orelse")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"test"),ctx.new_ascii_str(b"body"),ctx.new_ascii_str(b"orelse")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Dict", base = "AstNode")] @@ -358,8 +358,8 @@ struct NodeDict; impl NodeDict { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("keys"),ctx.new_str("values")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"keys"),ctx.new_ascii_str(b"values")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Set", base = "AstNode")] @@ -368,8 +368,8 @@ struct NodeSet; impl NodeSet { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("elts")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"elts")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "ListComp", base = "AstNode")] @@ -378,8 +378,8 @@ struct NodeListComp; impl NodeListComp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("elt"),ctx.new_str("generators")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"elt"),ctx.new_ascii_str(b"generators")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "SetComp", base = "AstNode")] @@ -388,8 +388,8 @@ struct NodeSetComp; impl NodeSetComp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("elt"),ctx.new_str("generators")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"elt"),ctx.new_ascii_str(b"generators")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "DictComp", base = "AstNode")] @@ -398,8 +398,8 @@ struct NodeDictComp; impl NodeDictComp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("key"),ctx.new_str("value"),ctx.new_str("generators")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"key"),ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"generators")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "GeneratorExp", base = "AstNode")] @@ -408,8 +408,8 @@ struct NodeGeneratorExp; impl NodeGeneratorExp { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("elt"),ctx.new_str("generators")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"elt"),ctx.new_ascii_str(b"generators")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Await", base = "AstNode")] @@ -418,8 +418,8 @@ struct NodeAwait; impl NodeAwait { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Yield", base = "AstNode")] @@ -428,8 +428,8 @@ struct NodeYield; impl NodeYield { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "YieldFrom", base = "AstNode")] @@ -438,8 +438,8 @@ struct NodeYieldFrom; impl NodeYieldFrom { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Compare", base = "AstNode")] @@ -448,8 +448,8 @@ struct NodeCompare; impl NodeCompare { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("left"),ctx.new_str("ops"),ctx.new_str("comparators")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"left"),ctx.new_ascii_str(b"ops"),ctx.new_ascii_str(b"comparators")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Call", base = "AstNode")] @@ -458,8 +458,8 @@ struct NodeCall; impl NodeCall { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("func"),ctx.new_str("args"),ctx.new_str("keywords")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"func"),ctx.new_ascii_str(b"args"),ctx.new_ascii_str(b"keywords")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "FormattedValue", base = "AstNode")] @@ -468,8 +468,8 @@ struct NodeFormattedValue; impl NodeFormattedValue { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value"),ctx.new_str("conversion"),ctx.new_str("format_spec")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"conversion"),ctx.new_ascii_str(b"format_spec")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "JoinedStr", base = "AstNode")] @@ -478,8 +478,8 @@ struct NodeJoinedStr; impl NodeJoinedStr { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("values")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"values")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Constant", base = "AstNode")] @@ -488,8 +488,8 @@ struct NodeConstant; impl NodeConstant { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value"),ctx.new_str("kind")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"kind")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Attribute", base = "AstNode")] @@ -498,8 +498,8 @@ struct NodeAttribute; impl NodeAttribute { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value"),ctx.new_str("attr"),ctx.new_str("ctx")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"attr"),ctx.new_ascii_str(b"ctx")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Subscript", base = "AstNode")] @@ -508,8 +508,8 @@ struct NodeSubscript; impl NodeSubscript { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value"),ctx.new_str("slice"),ctx.new_str("ctx")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"slice"),ctx.new_ascii_str(b"ctx")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Starred", base = "AstNode")] @@ -518,8 +518,8 @@ struct NodeStarred; impl NodeStarred { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("value"),ctx.new_str("ctx")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"value"),ctx.new_ascii_str(b"ctx")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Name", base = "AstNode")] @@ -528,8 +528,8 @@ struct NodeName; impl NodeName { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("id"),ctx.new_str("ctx")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"id"),ctx.new_ascii_str(b"ctx")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "List", base = "AstNode")] @@ -538,8 +538,8 @@ struct NodeList; impl NodeList { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("elts"),ctx.new_str("ctx")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"elts"),ctx.new_ascii_str(b"ctx")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Tuple", base = "AstNode")] @@ -548,8 +548,8 @@ struct NodeTuple; impl NodeTuple { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("elts"),ctx.new_str("ctx")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"elts"),ctx.new_ascii_str(b"ctx")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Slice", base = "AstNode")] @@ -558,8 +558,8 @@ struct NodeSlice; impl NodeSlice { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("lower"),ctx.new_str("upper"),ctx.new_str("step")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"lower"),ctx.new_ascii_str(b"upper"),ctx.new_ascii_str(b"step")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "Load", base = "AstNode")] @@ -888,7 +888,7 @@ struct Nodecomprehension; impl Nodecomprehension { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("target"),ctx.new_str("iter"),ctx.new_str("ifs"),ctx.new_str("is_async")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"target"),ctx.new_ascii_str(b"iter"),ctx.new_ascii_str(b"ifs"),ctx.new_ascii_str(b"is_async")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -898,8 +898,8 @@ struct NodeExceptHandler; impl NodeExceptHandler { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("type"),ctx.new_str("name"),ctx.new_str("body")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"type"),ctx.new_ascii_str(b"name"),ctx.new_ascii_str(b"body")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "arguments", base = "AstNode")] @@ -908,7 +908,7 @@ struct Nodearguments; impl Nodearguments { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("posonlyargs"),ctx.new_str("args"),ctx.new_str("vararg"),ctx.new_str("kwonlyargs"),ctx.new_str("kw_defaults"),ctx.new_str("kwarg"),ctx.new_str("defaults")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"posonlyargs"),ctx.new_ascii_str(b"args"),ctx.new_ascii_str(b"vararg"),ctx.new_ascii_str(b"kwonlyargs"),ctx.new_ascii_str(b"kw_defaults"),ctx.new_ascii_str(b"kwarg"),ctx.new_ascii_str(b"defaults")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -918,8 +918,8 @@ struct Nodearg; impl Nodearg { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("arg"),ctx.new_str("annotation"),ctx.new_str("type_comment")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"arg"),ctx.new_ascii_str(b"annotation"),ctx.new_ascii_str(b"type_comment")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "keyword", base = "AstNode")] @@ -928,8 +928,8 @@ struct Nodekeyword; impl Nodekeyword { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("arg"),ctx.new_str("value")])); - class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("col_offset"),ctx.new_str("end_lineno"),ctx.new_str("end_col_offset")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"arg"),ctx.new_ascii_str(b"value")])); + class.set_str_attr("_attributes", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"col_offset"),ctx.new_ascii_str(b"end_lineno"),ctx.new_ascii_str(b"end_col_offset")])); } } #[pyclass(module = "_ast", name = "alias", base = "AstNode")] @@ -938,7 +938,7 @@ struct Nodealias; impl Nodealias { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("name"),ctx.new_str("asname")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"name"),ctx.new_ascii_str(b"asname")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -948,7 +948,7 @@ struct Nodewithitem; impl Nodewithitem { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("context_expr"),ctx.new_str("optional_vars")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"context_expr"),ctx.new_ascii_str(b"optional_vars")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } @@ -958,7 +958,7 @@ struct NodeTypeIgnore; impl NodeTypeIgnore { #[extend_class] fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) { - class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_str("lineno"),ctx.new_str("tag")])); + class.set_str_attr("_fields", ctx.new_list(vec![ctx.new_ascii_str(b"lineno"),ctx.new_ascii_str(b"tag")])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } } diff --git a/vm/src/stdlib/codecs.rs b/vm/src/stdlib/codecs.rs index 45f730af23..0ce376f6e3 100644 --- a/vm/src/stdlib/codecs.rs +++ b/vm/src/stdlib/codecs.rs @@ -126,11 +126,11 @@ mod _codecs { let decode_exc = vm.new_exception( vm.ctx.exceptions.unicode_decode_error.clone(), vec![ - vm.ctx.new_str(self.encoding), + vm.ctx.new_utf8_str(self.encoding), data_bytes.clone(), vm.ctx.new_int(byte_range.start), vm.ctx.new_int(byte_range.end), - vm.ctx.new_str(reason), + vm.ctx.new_utf8_str(reason), ], ); let res = vm.invoke(self.handler_func()?, (decode_exc.clone(),))?; diff --git a/vm/src/stdlib/csv.rs b/vm/src/stdlib/csv.rs index 6b1376f58a..a5058d1b0f 100644 --- a/vm/src/stdlib/csv.rs +++ b/vm/src/stdlib/csv.rs @@ -160,7 +160,7 @@ impl PyIter for Reader { let range = prev_end..end; prev_end = end; std::str::from_utf8(&buffer[range]) - .map(|s| vm.ctx.new_str(s.to_owned())) + .map(|s| vm.ctx.new_utf8_str(s.to_owned())) // not sure if this is possible - the input was all strings .map_err(|_e| vm.new_unicode_decode_error("csv not utf8".to_owned())) }) diff --git a/vm/src/stdlib/dis.rs b/vm/src/stdlib/dis.rs index d65d5a9684..2c7a3bd671 100644 --- a/vm/src/stdlib/dis.rs +++ b/vm/src/stdlib/dis.rs @@ -37,12 +37,8 @@ mod decl { fn compiler_flag_names(vm: &VirtualMachine) -> PyDictRef { let dict = vm.ctx.new_dict(); for (name, flag) in CodeFlags::NAME_MAPPING { - dict.set_item( - vm.ctx.new_int(flag.bits()), - vm.ctx.new_str((*name).to_owned()), - vm, - ) - .unwrap(); + dict.set_item(vm.ctx.new_int(flag.bits()), vm.ctx.new_utf8_str(name), vm) + .unwrap(); } dict } diff --git a/vm/src/stdlib/errno.rs b/vm/src/stdlib/errno.rs index 12e8593091..87fd236a15 100644 --- a/vm/src/stdlib/errno.rs +++ b/vm/src/stdlib/errno.rs @@ -7,7 +7,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "errorcode" => errorcode.clone(), }); for (name, code) in ERROR_CODES { - let name = vm.ctx.new_str((*name).to_owned()); + let name = vm.ctx.new_utf8_str((*name).to_owned()); let code = vm.ctx.new_int(*code); errorcode.set_item(code.clone(), name.clone(), vm).unwrap(); vm.set_attr(&module, name, code).unwrap(); diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 456160aa90..75f64893b3 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -3140,7 +3140,7 @@ mod _io { #[pymethod] fn getvalue(self, vm: &VirtualMachine) -> PyResult { match String::from_utf8(self.buffer(vm)?.getvalue()) { - Ok(result) => Ok(vm.ctx.new_str(result)), + Ok(result) => Ok(vm.ctx.new_utf8_str(result)), Err(_) => Err(vm.new_value_error("Error Retrieving Value".to_owned())), } } @@ -3168,10 +3168,9 @@ mod _io { None => Vec::new(), }; - match String::from_utf8(data) { - Ok(value) => Ok(vm.ctx.new_str(value)), - Err(_) => Err(vm.new_value_error("Error Retrieving Value".to_owned())), - } + let value = String::from_utf8(data) + .map_err(|_| vm.new_value_error("Error Retrieving Value".to_owned()))?; + Ok(vm.ctx.new_utf8_str(value)) } #[pymethod] @@ -3640,7 +3639,7 @@ mod _io { line_buffering, ), )?; - vm.set_attr(&wrapper, "mode", vm.ctx.new_str(mode_string))?; + vm.set_attr(&wrapper, "mode", vm.ctx.new_utf8_str(mode_string))?; Ok(wrapper) } EncodeMode::Bytes => Ok(buffered), diff --git a/vm/src/stdlib/keyword.rs b/vm/src/stdlib/keyword.rs index 2100d7a248..9477427d52 100644 --- a/vm/src/stdlib/keyword.rs +++ b/vm/src/stdlib/keyword.rs @@ -25,7 +25,7 @@ mod decl { lexer::KEYWORDS .keys() .sorted() - .map(|k| vm.ctx.new_str(k.to_owned())) + .map(|k| vm.ctx.new_utf8_str(k)) .collect(), ) } diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index b06adb4fed..818d0628be 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -63,7 +63,7 @@ impl OutputMode { }) }; match mode { - OutputMode::String => path_as_string(path).map(|s| vm.ctx.new_str(s)), + OutputMode::String => path_as_string(path).map(|s| vm.ctx.new_utf8_str(s)), OutputMode::Bytes => { #[cfg(any(unix, target_os = "wasi"))] { @@ -262,7 +262,7 @@ impl IntoPyException for &'_ io::Error { }, }; let errno = self.raw_os_error().into_pyobject(vm); - let msg = vm.ctx.new_str(self.to_string()); + let msg = vm.ctx.new_utf8_str(self.to_string()); vm.new_exception(exc_type, vec![errno, msg]) } } @@ -2769,7 +2769,7 @@ mod posix { Err(errno_err(vm)) } else { let name = unsafe { ffi::CStr::from_ptr(name) }.to_str().unwrap(); - Ok(vm.ctx.new_str(name)) + Ok(vm.ctx.new_utf8_str(name)) } } @@ -3386,7 +3386,7 @@ mod nt { for (key, value) in env::vars() { environ - .set_item(vm.ctx.new_str(key), vm.ctx.new_str(value), vm) + .set_item(vm.ctx.new_utf8_str(key), vm.ctx.new_utf8_str(value), vm) .unwrap(); } environ diff --git a/vm/src/stdlib/pwd.rs b/vm/src/stdlib/pwd.rs index a544075388..d3deae9f2a 100644 --- a/vm/src/stdlib/pwd.rs +++ b/vm/src/stdlib/pwd.rs @@ -53,7 +53,7 @@ fn pwd_getpwnam(name: PyStrRef, vm: &VirtualMachine) -> PyResult { let name_repr = vm.to_repr(name.as_object())?; let message = vm .ctx - .new_str(format!("getpwnam(): name not found: {}", name_repr)); + .new_utf8_str(format!("getpwnam(): name not found: {}", name_repr)); Err(vm.new_key_error(message)) } } @@ -70,7 +70,7 @@ fn pwd_getpwuid(uid: PyIntRef, vm: &VirtualMachine) -> PyResult { None => { let message = vm .ctx - .new_str(format!("getpwuid(): uid not found: {}", uid.as_bigint())); + .new_utf8_str(format!("getpwuid(): uid not found: {}", uid.as_bigint())); Err(vm.new_key_error(message)) } } diff --git a/vm/src/stdlib/pyexpat.rs b/vm/src/stdlib/pyexpat.rs index 4c37730d99..ecc73ddf70 100644 --- a/vm/src/stdlib/pyexpat.rs +++ b/vm/src/stdlib/pyexpat.rs @@ -140,7 +140,7 @@ mod _pyexpat { for attribute in attributes { dict.set_item( attribute.name.local_name.as_str(), - vm.ctx.new_str(attribute.value), + vm.ctx.new_utf8_str(attribute.value), vm, ) .unwrap(); diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs index b40741f9f6..bbda297dc0 100644 --- a/vm/src/stdlib/re.rs +++ b/vm/src/stdlib/re.rs @@ -183,12 +183,12 @@ fn do_findall(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStrRef) - 1 => { let full = captures.get(0).unwrap().as_bytes(); let full = String::from_utf8_lossy(full).into_owned(); - vm.ctx.new_str(full) + vm.ctx.new_utf8_str(full) } 2 => { let capture = captures.get(1).unwrap().as_bytes(); let capture = String::from_utf8_lossy(capture).into_owned(); - vm.ctx.new_str(capture) + vm.ctx.new_utf8_str(capture) } _ => { let out = captures @@ -198,7 +198,7 @@ fn do_findall(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStrRef) - let s = m .map(|m| String::from_utf8_lossy(m.as_bytes()).into_owned()) .unwrap_or_default(); - vm.ctx.new_str(s) + vm.ctx.new_utf8_str(s) }) .collect(); vm.ctx.new_tuple(out) @@ -246,7 +246,7 @@ fn do_split( let split = output .into_iter() .map(|v| { - vm.unwrap_or_none(v.map(|v| vm.ctx.new_str(String::from_utf8_lossy(v).into_owned()))) + vm.unwrap_or_none(v.map(|v| vm.ctx.new_utf8_str(String::from_utf8_lossy(v).into_owned()))) }) .collect(); Ok(vm.ctx.new_list(split)) @@ -324,7 +324,7 @@ impl PyPattern { .regex .replace_all(text.as_str().as_bytes(), repl.as_str().as_bytes()); let replaced_text = String::from_utf8_lossy(&replaced_text).into_owned(); - Ok(vm.ctx.new_str(replaced_text)) + Ok(vm.ctx.new_utf8_str(replaced_text)) } #[pymethod] @@ -334,7 +334,7 @@ impl PyPattern { #[pyproperty] fn pattern(&self, vm: &VirtualMachine) -> PyResult { - Ok(vm.ctx.new_str(self.pattern.clone())) + Ok(vm.ctx.new_utf8_str(self.pattern.clone())) } #[pymethod] diff --git a/vm/src/stdlib/scproxy.rs b/vm/src/stdlib/scproxy.rs index b5c8867afe..3a2824e0f0 100644 --- a/vm/src/stdlib/scproxy.rs +++ b/vm/src/stdlib/scproxy.rs @@ -106,7 +106,7 @@ mod _scproxy { } else { format!("http://{}", h) }; - result.set_item(proto, vm.ctx.new_str(v), vm)?; + result.set_item(proto, vm.ctx.new_utf8_str(v), vm)?; } } Ok(()) diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 90359c3672..de652d4367 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -1030,7 +1030,8 @@ fn get_addr_tuple(addr: &socket2::SockAddr, vm: &VirtualMachine) -> PyObjectRef } else { let len = memchr::memchr(b'\0', path_u8).unwrap_or_else(|| path_u8.len()); let path = &path_u8[..len]; - vm.ctx.new_str(String::from_utf8_lossy(path).into_owned()) + vm.ctx + .new_utf8_str(String::from_utf8_lossy(path).into_owned()) } } // TODO: support more address families @@ -1041,7 +1042,7 @@ fn get_addr_tuple(addr: &socket2::SockAddr, vm: &VirtualMachine) -> PyObjectRef fn _socket_gethostname(vm: &VirtualMachine) -> PyResult { gethostname() .into_string() - .map(|hostname| vm.ctx.new_str(hostname)) + .map(|hostname| vm.ctx.new_utf8_str(hostname)) .map_err(|err| vm.new_os_error(err.into_string().unwrap())) } @@ -1062,7 +1063,7 @@ fn _socket_inet_ntoa(packed_ip: ArgBytesLike, vm: &VirtualMachine) -> PyResult { let packed_ip = packed_ip.borrow_buf(); let packed_ip = <&[u8; 4]>::try_from(&*packed_ip) .map_err(|_| vm.new_os_error("packed IP wrong length for inet_ntoa".to_owned()))?; - Ok(vm.ctx.new_str(Ipv4Addr::from(*packed_ip).to_string())) + Ok(vm.ctx.new_utf8_str(Ipv4Addr::from(*packed_ip).to_string())) } fn cstr_opt_as_ptr(x: &OptionalArg) -> *const libc::c_char { @@ -1291,7 +1292,8 @@ fn _socket_gethostbyaddr( Ok(( hostname, vm.ctx.new_list(vec![]), - vm.ctx.new_list(vec![vm.ctx.new_str(addr.ip().to_string())]), + vm.ctx + .new_list(vec![vm.ctx.new_utf8_str(addr.ip().to_string())]), )) } @@ -1727,7 +1729,7 @@ fn convert_socket_error( }; vm.new_exception( exception_cls.get().unwrap().clone(), - vec![vm.ctx.new_int(err.error_num()), vm.ctx.new_str(strerr)], + vec![vm.ctx.new_int(err.error_num()), vm.ctx.new_utf8_str(strerr)], ) } diff --git a/vm/src/stdlib/sre.rs b/vm/src/stdlib/sre.rs index 44d0f1278c..af6c5f7e4e 100644 --- a/vm/src/stdlib/sre.rs +++ b/vm/src/stdlib/sre.rs @@ -57,7 +57,7 @@ mod _sre { match this { StrDrive::Str(s) => vm .ctx - .new_str(s.chars().take(end).skip(start).collect::()), + .new_utf8_str(s.chars().take(end).skip(start).collect::()), StrDrive::Bytes(b) => vm .ctx .new_bytes(b.iter().take(end).skip(start).cloned().collect()), @@ -274,7 +274,7 @@ mod _sre { m.get_slice(zelf.groups, state.string, vm) .unwrap_or_else(|| vm.ctx.none()) } else { - m.groups(OptionalArg::Present(vm.ctx.new_str("")), vm)? + m.groups(OptionalArg::Present(vm.ctx.new_ascii_str(b"")), vm)? .into_object() }; @@ -510,7 +510,7 @@ mod _sre { let join_type = if zelf.isbytes { vm.ctx.new_bytes(vec![]) } else { - vm.ctx.new_str("") + vm.ctx.new_ascii_str(b"") }; let ret = vm.call_method(&join_type, "join", (list,))?; diff --git a/vm/src/stdlib/ssl.rs b/vm/src/stdlib/ssl.rs index 433dbead7c..14f33c3fb4 100644 --- a/vm/src/stdlib/ssl.rs +++ b/vm/src/stdlib/ssl.rs @@ -77,8 +77,8 @@ enum ProtoVersion { } // taken from CPython, should probably be kept up to date with their version if it ever changes -const DEFAULT_CIPHER_STRING: &str = - "DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK"; +const DEFAULT_CIPHER_STRING: &[u8] = + b"DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK"; #[derive(num_enum::IntoPrimitive, num_enum::TryFromPrimitive)] #[repr(i32)] @@ -155,14 +155,14 @@ fn _ssl_enum_certificates(store_name: PyStrRef, vm: &VirtualMachine) -> PyResult (*ptr).dwCertEncodingType }; let enc_type = match enc_type { - wincrypt::X509_ASN_ENCODING => vm.ctx.new_str("x509_asn"), - wincrypt::PKCS_7_ASN_ENCODING => vm.ctx.new_str("pkcs_7_asn"), + wincrypt::X509_ASN_ENCODING => vm.ctx.new_ascii_str(b"x509_asn"), + wincrypt::PKCS_7_ASN_ENCODING => vm.ctx.new_ascii_str(b"pkcs_7_asn"), other => vm.ctx.new_int(other), }; let usage = match c.valid_uses()? { ValidUses::All => vm.ctx.new_bool(true), ValidUses::Oids(oids) => { - PyFrozenSet::from_iter(vm, oids.into_iter().map(|oid| vm.ctx.new_str(oid))) + PyFrozenSet::from_iter(vm, oids.into_iter().map(|oid| vm.ctx.new_utf8_str(oid))) .unwrap() .into_ref(vm) .into_object() @@ -966,7 +966,7 @@ fn convert_openssl_error(vm: &VirtualMachine, err: ErrorStack) -> PyBaseExceptio let errstr = e.reason().unwrap_or("unknown error"); let msg = format!("{} (_ssl.c:{})", errstr, e.line()); let reason = sys::ERR_GET_REASON(e.code()); - vm.new_exception(cls, vec![vm.ctx.new_int(reason), vm.ctx.new_str(msg)]) + vm.new_exception(cls, vec![vm.ctx.new_int(reason), vm.ctx.new_utf8_str(msg)]) } None => vm.new_exception_empty(cls), } @@ -1019,7 +1019,7 @@ fn cert_to_py(vm: &VirtualMachine, cert: &X509Ref, binary: bool) -> PyResult { name.entries() .map(|entry| { let txt = obj2txt(entry.object(), false).into_pyobject(vm); - let data = vm.ctx.new_str(entry.data().as_utf8()?.to_owned()); + let data = vm.ctx.new_utf8_str(entry.data().as_utf8()?.to_owned()); Ok(vm.ctx.new_tuple(vec![vm.ctx.new_tuple(vec![txt, data])])) }) .collect::>() @@ -1038,14 +1038,22 @@ fn cert_to_py(vm: &VirtualMachine, cert: &X509Ref, binary: bool) -> PyResult { .to_bn() .and_then(|bn| bn.to_hex_str()) .map_err(|e| convert_openssl_error(vm, e))?; - dict.set_item("serialNumber", vm.ctx.new_str(serial_num.to_owned()), vm)?; + dict.set_item( + "serialNumber", + vm.ctx.new_utf8_str(serial_num.to_owned()), + vm, + )?; dict.set_item( "notBefore", - vm.ctx.new_str(cert.not_before().to_string()), + vm.ctx.new_utf8_str(cert.not_before().to_string()), + vm, + )?; + dict.set_item( + "notAfter", + vm.ctx.new_utf8_str(cert.not_after().to_string()), vm, )?; - dict.set_item("notAfter", vm.ctx.new_str(cert.not_after().to_string()), vm)?; #[allow(clippy::manual_map)] if let Some(names) = cert.subject_alt_names() { @@ -1053,19 +1061,19 @@ fn cert_to_py(vm: &VirtualMachine, cert: &X509Ref, binary: bool) -> PyResult { .iter() .filter_map(|gen_name| { if let Some(email) = gen_name.email() { - Some( - vm.ctx - .new_tuple(vec![vm.ctx.new_str("email"), vm.ctx.new_str(email)]), - ) + Some(vm.ctx.new_tuple(vec![ + vm.ctx.new_ascii_str(b"email"), + vm.ctx.new_utf8_str(email), + ])) } else if let Some(dnsname) = gen_name.dnsname() { - Some( - vm.ctx - .new_tuple(vec![vm.ctx.new_str("DNS"), vm.ctx.new_str(dnsname)]), - ) + Some(vm.ctx.new_tuple(vec![ + vm.ctx.new_ascii_str(b"DNS"), + vm.ctx.new_utf8_str(dnsname), + ])) } else if let Some(ip) = gen_name.ipaddress() { Some(vm.ctx.new_tuple(vec![ - vm.ctx.new_str("IP Address"), - vm.ctx.new_str(String::from_utf8_lossy(ip).into_owned()), + vm.ctx.new_ascii_str(b"IP Address"), + vm.ctx.new_utf8_str(String::from_utf8_lossy(ip).into_owned()), ])) } else { // TODO: convert every type of general name: @@ -1151,11 +1159,11 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "_test_decode_cert" => named_function!(ctx, _ssl, _test_decode_cert), // Constants - "OPENSSL_VERSION" => ctx.new_str(openssl::version::version().to_owned()), + "OPENSSL_VERSION" => ctx.new_utf8_str(openssl::version::version()), "OPENSSL_VERSION_NUMBER" => ctx.new_int(openssl::version::number()), "OPENSSL_VERSION_INFO" => parse_version_info(openssl::version::number()).into_pyobject(vm), "_OPENSSL_API_VERSION" => parse_version_info(openssl_api_version).into_pyobject(vm), - "_DEFAULT_CIPHERS" => ctx.new_str(DEFAULT_CIPHER_STRING), + "_DEFAULT_CIPHERS" => ctx.new_ascii_str(DEFAULT_CIPHER_STRING), // "PROTOCOL_SSLv2" => ctx.new_int(SslVersion::Ssl2 as u32), unsupported // "PROTOCOL_SSLv3" => ctx.new_int(SslVersion::Ssl3 as u32), "PROTOCOL_SSLv23" => ctx.new_int(SslVersion::Tls as u32), diff --git a/vm/src/stdlib/string.rs b/vm/src/stdlib/string.rs index 7ea769195a..b193674794 100644 --- a/vm/src/stdlib/string.rs +++ b/vm/src/stdlib/string.rs @@ -77,7 +77,7 @@ mod _string { let field_name = FieldName::parse(text.as_str()).map_err(|e| e.into_pyexception(vm))?; let first = match field_name.field_type { - FieldType::Auto => vm.ctx.new_str("".to_owned()), + FieldType::Auto => vm.ctx.new_ascii_str(b""), FieldType::Index(index) => index.into_pyobject(vm), FieldType::Keyword(attribute) => attribute.into_pyobject(vm), }; diff --git a/vm/src/stdlib/symtable.rs b/vm/src/stdlib/symtable.rs index 3e9918a9ec..2a77058f1f 100644 --- a/vm/src/stdlib/symtable.rs +++ b/vm/src/stdlib/symtable.rs @@ -99,7 +99,7 @@ mod decl { } .into_ref(vm)) } else { - Err(vm.new_key_error(vm.ctx.new_str(format!("lookup {} failed", name)))) + Err(vm.new_key_error(vm.ctx.new_utf8_str(format!("lookup {} failed", name)))) } } @@ -109,7 +109,7 @@ mod decl { .symtable .symbols .keys() - .map(|s| vm.ctx.new_str(s)) + .map(|s| vm.ctx.new_utf8_str(s)) .collect(); Ok(vm.ctx.new_list(symbols)) } diff --git a/vm/src/stdlib/termios.rs b/vm/src/stdlib/termios.rs index d842f1c71e..6d9ec82bd9 100644 --- a/vm/src/stdlib/termios.rs +++ b/vm/src/stdlib/termios.rs @@ -98,7 +98,7 @@ mod termios { get_termios_error(vm), vec![ err.raw_os_error().into_pyobject(vm), - vm.ctx.new_str(err.to_string()), + vm.ctx.new_utf8_str(err.to_string()), ], ) } diff --git a/vm/src/stdlib/time.rs b/vm/src/stdlib/time.rs index e49f988296..df1a540793 100644 --- a/vm/src/stdlib/time.rs +++ b/vm/src/stdlib/time.rs @@ -165,7 +165,7 @@ mod time { fn asctime(t: OptionalArg, vm: &VirtualMachine) -> PyResult { let instant = t.naive_or_local(vm)?; let formatted_time = instant.format(CFMT).to_string(); - Ok(vm.ctx.new_str(formatted_time)) + Ok(vm.ctx.new_utf8_str(formatted_time)) } #[pyfunction] @@ -178,7 +178,7 @@ mod time { fn strftime(format: PyStrRef, t: OptionalArg, vm: &VirtualMachine) -> PyResult { let instant = t.naive_or_local(vm)?; let formatted_time = instant.format(format.as_str()).to_string(); - Ok(vm.ctx.new_str(formatted_time)) + Ok(vm.ctx.new_utf8_str(formatted_time)) } #[pyfunction] diff --git a/vm/src/stdlib/unicodedata.rs b/vm/src/stdlib/unicodedata.rs index 741cb979f6..bc675d99b3 100644 --- a/vm/src/stdlib/unicodedata.rs +++ b/vm/src/stdlib/unicodedata.rs @@ -39,7 +39,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "ucd_3_2_0" => ucd_3_2_0, // we do unidata_version here because the getter tries to do PyUCD::class() before // the module is in the VM - "unidata_version" => ctx.new_str(PyUCD::default().unic_version.to_string()), + "unidata_version" => ctx.new_utf8_str(PyUCD::default().unic_version.to_string()), }); for attr in ["category", "lookup", "name", "bidirectional", "normalize"] @@ -124,7 +124,7 @@ impl PyUCD { if let Some(c) = c { if self.check_age(c) { if let Some(name) = unicode_names2::name(c) { - return Ok(vm.ctx.new_str(name.to_string())); + return Ok(vm.ctx.new_utf8_str(name.to_string())); } } } diff --git a/vm/src/stdlib/winreg.rs b/vm/src/stdlib/winreg.rs index 962d152979..7954c89905 100644 --- a/vm/src/stdlib/winreg.rs +++ b/vm/src/stdlib/winreg.rs @@ -260,7 +260,7 @@ fn reg_to_py(value: RegValue, vm: &VirtualMachine) -> PyResult { .position(|w| *w == 0) .unwrap_or_else(|| wide_slice.len()); let s = String::from_utf16_lossy(&wide_slice[..nul_pos]); - Ok(vm.ctx.new_str(s)) + Ok(vm.ctx.new_utf8_str(s)) } RegType::REG_MULTI_SZ => { if value.bytes.is_empty() { @@ -278,7 +278,7 @@ fn reg_to_py(value: RegValue, vm: &VirtualMachine) -> PyResult { }; let strings = wide_slice .split(|c| *c == 0) - .map(|s| vm.ctx.new_str(String::from_utf16_lossy(s))) + .map(|s| vm.ctx.new_utf8_str(String::from_utf16_lossy(s))) .collect(); Ok(vm.ctx.new_list(strings)) } diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index bc19f3c5d5..1dcac442e2 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -23,7 +23,7 @@ fn argv(vm: &VirtualMachine) -> PyObjectRef { .settings .argv .iter() - .map(|arg| vm.ctx.new_str(arg)) + .map(|arg| vm.ctx.new_utf8_str(arg)) .collect(), ) } @@ -33,7 +33,7 @@ fn executable(ctx: &PyContext) -> PyObjectRef { { if let Some(exec_path) = env::args_os().next() { if let Ok(path) = which::which(exec_path) { - return ctx.new_str( + return ctx.new_utf8_str( path.into_os_string() .into_string() .unwrap_or_else(|p| p.to_string_lossy().into_owned()), @@ -44,14 +44,14 @@ fn executable(ctx: &PyContext) -> PyObjectRef { if let Some(exec_path) = env::args().next() { let path = path::Path::new(&exec_path); if !path.exists() { - return ctx.new_str(""); + return ctx.new_ascii_str(b""); } if path.is_absolute() { - return ctx.new_str(exec_path); + return ctx.new_utf8_str(exec_path); } if let Ok(dir) = env::current_dir() { if let Ok(dir) = dir.into_os_string().into_string() { - return ctx.new_str(format!( + return ctx.new_utf8_str(format!( "{}/{}", dir, exec_path.strip_prefix("./").unwrap_or(&exec_path) @@ -64,7 +64,7 @@ fn executable(ctx: &PyContext) -> PyObjectRef { fn _base_executable(ctx: &PyContext) -> PyObjectRef { if let Ok(var) = env::var("__PYVENV_LAUNCHER__") { - ctx.new_str(var) + ctx.new_utf8_str(var) } else { executable(ctx) } @@ -237,9 +237,9 @@ fn sys_exc_info(vm: &VirtualMachine) -> (PyObjectRef, PyObjectRef, PyObjectRef) fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef { vm.ctx.new_tuple(vec![ - vm.ctx.new_str("RustPython"), - vm.ctx.new_str(version::get_git_identifier()), - vm.ctx.new_str(version::get_git_revision()), + vm.ctx.new_ascii_str(b"RustPython"), + vm.ctx.new_utf8_str(version::get_git_identifier()), + vm.ctx.new_utf8_str(version::get_git_revision()), ]) } @@ -513,9 +513,9 @@ pub(crate) fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: Py // TODO Add crate version to this namespace let implementation = py_namespace!(vm, { - "name" => ctx.new_str("rustpython"), - "cache_tag" => ctx.new_str("rustpython-01"), - "_multiarch" => ctx.new_str(MULTIARCH.to_owned()), + "name" => ctx.new_ascii_str(b"rustpython"), + "cache_tag" => ctx.new_ascii_str(b"rustpython-01"), + "_multiarch" => ctx.new_utf8_str(MULTIARCH.to_owned()), "version" => version_info.clone(), "hexversion" => ctx.new_int(version::VERSION_HEX), }); @@ -525,7 +525,7 @@ pub(crate) fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: Py .settings .path_list .iter() - .map(|path| ctx.new_str(path.clone())) + .map(|path| ctx.new_utf8_str(path.clone())) .collect(), ); @@ -535,7 +535,7 @@ pub(crate) fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: Py for (key, value) in &vm.state.settings.xopts { let value = value .as_ref() - .map_or_else(|| ctx.new_bool(true), |s| ctx.new_str(s.clone())); + .map_or_else(|| ctx.new_bool(true), |s| ctx.new_utf8_str(s.clone())); xopts.set_item(&**key, value, vm).unwrap(); } @@ -544,7 +544,7 @@ pub(crate) fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: Py .settings .warnopts .iter() - .map(|s| ctx.new_str(s.clone())) + .map(|s| ctx.new_utf8_str(s.clone())) .collect(), ); @@ -637,7 +637,7 @@ settrace() -- set the global debug tracing function let builtin_module_names = ctx.new_tuple( module_names .into_iter() - .map(|n| ctx.new_str(n.into_owned())) + .map(|n| ctx.new_utf8_str(n.into_owned())) .collect(), ); let modules = ctx.new_dict(); @@ -650,11 +650,11 @@ settrace() -- set the global debug tracing function let base_exec_prefix = option_env!("RUSTPYTHON_BASEEXECPREFIX").unwrap_or(exec_prefix); extend_module!(vm, module, { - "__name__" => ctx.new_str(String::from("sys")), + "__name__" => ctx.new_ascii_str(b"sys"), "argv" => argv(vm), "builtin_module_names" => builtin_module_names, - "byteorder" => ctx.new_str(bytorder), - "copyright" => ctx.new_str(copyright), + "byteorder" => ctx.new_utf8_str(bytorder), + "copyright" => ctx.new_utf8_str(copyright), "_base_executable" => _base_executable(ctx), "executable" => executable(ctx), "flags" => flags, @@ -672,13 +672,13 @@ settrace() -- set the global debug tracing function "maxunicode" => ctx.new_int(MAXUNICODE), "maxsize" => ctx.new_int(MAXSIZE), "path" => path, - "ps1" => ctx.new_str(">>>>> "), - "ps2" => ctx.new_str("..... "), - "__doc__" => ctx.new_str(sys_doc), + "ps1" => ctx.new_ascii_str(b">>>>> "), + "ps2" => ctx.new_ascii_str(b"..... "), + "__doc__" => ctx.new_utf8_str(sys_doc), "_getframe" => named_function!(ctx, sys, _getframe), "modules" => modules.clone(), - "platform" => ctx.new_str(PLATFORM.to_owned()), - "_framework" => ctx.new_str(framework), + "platform" => ctx.new_utf8_str(PLATFORM.to_owned()), + "_framework" => ctx.new_utf8_str(framework), "meta_path" => ctx.new_list(vec![]), "path_hooks" => ctx.new_list(vec![]), "path_importer_cache" => ctx.new_dict(), @@ -687,16 +687,16 @@ settrace() -- set the global debug tracing function "setprofile" => named_function!(ctx, sys, setprofile), "setrecursionlimit" => named_function!(ctx, sys, setrecursionlimit), "settrace" => named_function!(ctx, sys, settrace), - "version" => vm.ctx.new_str(version::get_version()), + "version" => vm.ctx.new_utf8_str(version::get_version()), "version_info" => version_info, "_git" => sys_git_info(vm), "exc_info" => named_function!(ctx, sys, exc_info), - "prefix" => ctx.new_str(prefix), - "base_prefix" => ctx.new_str(base_prefix), - "exec_prefix" => ctx.new_str(exec_prefix), - "base_exec_prefix" => ctx.new_str(base_exec_prefix), + "prefix" => ctx.new_utf8_str(prefix), + "base_prefix" => ctx.new_utf8_str(base_prefix), + "exec_prefix" => ctx.new_utf8_str(exec_prefix), + "base_exec_prefix" => ctx.new_utf8_str(base_exec_prefix), "exit" => named_function!(ctx, sys, exit), - "abiflags" => ctx.new_str(ABIFLAGS.to_owned()), + "abiflags" => ctx.new_utf8_str(ABIFLAGS.to_owned()), "audit" => named_function!(ctx, sys, audit), "displayhook" => named_function!(ctx, sys, displayhook), "__displayhook__" => named_function!(ctx, sys, displayhook), @@ -706,7 +706,7 @@ settrace() -- set the global debug tracing function "api_version" => ctx.new_int(0x0), // what C api? "float_info" => float_info, "int_info" => int_info, - "float_repr_style" => ctx.new_str("short"), + "float_repr_style" => ctx.new_ascii_str(b"short"), "_xoptions" => xopts, "warnoptions" => warnopts, "_rustpython_debugbuild" => ctx.new_bool(cfg!(debug_assertions)), diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 7905753ec8..c661117ab8 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -308,10 +308,15 @@ impl VirtualMachine { module::init_module_dict( &vm, &builtins_dict, - vm.ctx.new_str("builtins"), + vm.ctx.new_ascii_str(b"builtins"), + vm.ctx.none(), + ); + module::init_module_dict( + &vm, + &sysmod_dict, + vm.ctx.new_ascii_str(b"sys"), vm.ctx.none(), ); - module::init_module_dict(&vm, &sysmod_dict, vm.ctx.new_str("sys"), vm.ctx.none()); vm } @@ -621,7 +626,7 @@ impl VirtualMachine { /// [invoke]: rustpython_vm::exceptions::invoke /// [ctor]: rustpython_vm::exceptions::ExceptionCtor pub fn new_exception_msg(&self, exc_type: PyTypeRef, msg: String) -> PyBaseExceptionRef { - self.new_exception(exc_type, vec![self.ctx.new_str(msg)]) + self.new_exception(exc_type, vec![self.ctx.new_utf8_str(msg)]) } pub fn new_lookup_error(&self, msg: String) -> PyBaseExceptionRef { @@ -764,7 +769,7 @@ impl VirtualMachine { self.set_attr( syntax_error.as_object(), "filename", - self.ctx.new_str(error.source_path.clone()), + self.ctx.new_utf8_str(error.source_path.clone()), ) .unwrap(); syntax_error @@ -1219,7 +1224,7 @@ impl VirtualMachine { } let frame = frame_ref.unwrap().as_object().clone(); - let event = self.ctx.new_str(event.to_string()); + let event = self.ctx.new_utf8_str(event.to_string()); let args = vec![frame, event, self.ctx.none()]; // temporarily disable tracing, during the call to the @@ -2225,7 +2230,7 @@ mod tests { #[test] fn test_multiply_str() { Interpreter::default().enter(|vm| { - let a = vm.ctx.new_str(String::from("Hello ")); + let a = vm.ctx.new_ascii_str(b"Hello "); let b = vm.ctx.new_int(4_i32); let res = vm._mul(&a, &b).unwrap(); let value = res.payload::().unwrap(); diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index b20f21933c..84ccdec828 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -200,7 +200,7 @@ impl Element { vm: &VirtualMachine, ) -> PyObjectRef { match self.elem.get_attribute(attr.as_str()) { - Some(s) => vm.ctx.new_str(s), + Some(s) => vm.ctx.new_utf8_str(s), None => default.unwrap_or_none(vm), } } diff --git a/wasm/lib/src/vm_class.rs b/wasm/lib/src/vm_class.rs index 9cc69b1436..6818076c7c 100644 --- a/wasm/lib/src/vm_class.rs +++ b/wasm/lib/src/vm_class.rs @@ -264,7 +264,7 @@ impl WASMVirtualMachine { .map_err(convert::syntax_err)?; let attrs = vm.ctx.new_dict(); attrs - .set_item("__name__", vm.ctx.new_str(name.clone()), vm) + .set_item("__name__", vm.ctx.new_utf8_str(&name), vm) .into_js(vm)?; if let Some(imports) = imports {