Skip to content

Commit 00a0e45

Browse files
authored
Merge pull request #1387 from RustPython/coolreader18/string-hash-field
Add a hash field to PyString á la CPython, make PyString.value private
2 parents c52677a + f846cd7 commit 00a0e45

29 files changed

+149
-140
lines changed

vm/src/builtins.rs

+13-16
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn builtin_any(iterable: PyIterable<IntoPyBool>, vm: &VirtualMachine) -> PyResul
6060

6161
fn builtin_ascii(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
6262
let repr = vm.to_repr(&obj)?;
63-
let ascii = to_ascii(&repr.value);
63+
let ascii = to_ascii(repr.as_str());
6464
Ok(ascii)
6565
}
6666

@@ -126,9 +126,9 @@ struct CompileArgs {
126126
#[cfg(feature = "rustpython-compiler")]
127127
fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult<PyCodeRef> {
128128
// TODO: compile::compile should probably get bytes
129-
let source = match args.source {
130-
Either::A(string) => string.value.to_string(),
131-
Either::B(bytes) => str::from_utf8(&bytes).unwrap().to_string(),
129+
let source = match &args.source {
130+
Either::A(string) => string.as_str(),
131+
Either::B(bytes) => str::from_utf8(bytes).unwrap(),
132132
};
133133

134134
let mode = args
@@ -137,7 +137,7 @@ fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult<PyCodeRef
137137
.parse::<compile::Mode>()
138138
.map_err(|err| vm.new_value_error(err.to_string()))?;
139139

140-
vm.compile(&source, mode, args.filename.value.to_string())
140+
vm.compile(source, mode, args.filename.as_str().to_string())
141141
.map_err(|err| vm.new_syntax_error(&err))
142142
}
143143

@@ -250,12 +250,9 @@ fn builtin_format(
250250
format_spec: OptionalArg<PyStringRef>,
251251
vm: &VirtualMachine,
252252
) -> PyResult<PyStringRef> {
253-
let format_spec = format_spec.into_option().unwrap_or_else(|| {
254-
PyString {
255-
value: "".to_string(),
256-
}
257-
.into_ref(vm)
258-
});
253+
let format_spec = format_spec
254+
.into_option()
255+
.unwrap_or_else(|| PyString::from("").into_ref(vm));
259256

260257
vm.call_method(&value, "__format__", vec![format_spec.into_object()])?
261258
.downcast()
@@ -598,8 +595,8 @@ impl Printer for &'_ PyObjectRef {
598595

599596
impl Printer for std::io::StdoutLock<'_> {
600597
fn write(&mut self, vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<()> {
601-
let s = &vm.to_str(&obj)?.value;
602-
write!(self, "{}", s).unwrap();
598+
let s = vm.to_str(&obj)?;
599+
write!(self, "{}", s.as_str()).unwrap();
603600
Ok(())
604601
}
605602

@@ -631,7 +628,7 @@ pub fn builtin_print(objects: Args, options: PrintOptions, vm: &VirtualMachine)
631628
let sep = options
632629
.sep
633630
.as_ref()
634-
.map_or(" ", |sep| &sep.value)
631+
.map_or(" ", |sep| sep.as_str())
635632
.into_pyobject(vm)
636633
.unwrap();
637634

@@ -649,7 +646,7 @@ pub fn builtin_print(objects: Args, options: PrintOptions, vm: &VirtualMachine)
649646
let end = options
650647
.end
651648
.as_ref()
652-
.map_or("\n", |end| &end.value)
649+
.map_or("\n", |end| end.as_str())
653650
.into_pyobject(vm)
654651
.unwrap();
655652
printer.write(vm, end)?;
@@ -902,7 +899,7 @@ pub fn builtin_build_class_(
902899
mut kwargs: KwArgs,
903900
vm: &VirtualMachine,
904901
) -> PyResult {
905-
let name = qualified_name.value.split('.').next_back().unwrap();
902+
let name = qualified_name.as_str().split('.').next_back().unwrap();
906903
let name_obj = vm.new_str(name.to_string());
907904

908905
let mut metaclass = if let Some(metaclass) = kwargs.pop_kwarg("metaclass") {

vm/src/dictdatatype.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ impl DictKey for &str {
330330

331331
fn do_eq(self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
332332
if let Some(py_str_value) = other_key.payload::<PyString>() {
333-
Ok(py_str_value.value == self)
333+
Ok(py_str_value.as_str() == self)
334334
} else {
335335
// Fall back to PyString implementation.
336336
let s = vm.new_str(self.to_string());
@@ -357,7 +357,7 @@ impl DictKey for &String {
357357

358358
fn do_eq(self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
359359
if let Some(py_str_value) = other_key.payload::<PyString>() {
360-
Ok(&py_str_value.value == self)
360+
Ok(py_str_value.as_str() == self)
361361
} else {
362362
// Fall back to PyString implementation.
363363
let s = vm.new_str(self.to_string());

vm/src/exceptions.rs

+22-21
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub fn print_exception(vm: &VirtualMachine, exc: &PyObjectRef) {
4444
print_exception_inner(vm, exc)
4545
}
4646

47-
fn print_source_line(filename: String, lineno: usize) {
47+
fn print_source_line(filename: &str, lineno: usize) {
4848
// TODO: use io.open() method instead, when available, according to https://github.com/python/cpython/blob/master/Python/traceback.c#L393
4949
// TODO: support different encodings
5050
let file = match File::open(filename) {
@@ -70,22 +70,26 @@ fn print_source_line(filename: String, lineno: usize) {
7070
fn print_traceback_entry(vm: &VirtualMachine, tb_entry: &PyObjectRef) {
7171
if objtype::isinstance(&tb_entry, &vm.ctx.tuple_type()) {
7272
let location_attrs = objsequence::get_elements_tuple(&tb_entry);
73-
let filename = if let Ok(x) = vm.to_str(&location_attrs[0]) {
74-
x.value.clone()
73+
74+
let filename = vm.to_str(&location_attrs[0]);
75+
let filename = if let Ok(ref x) = filename {
76+
x.as_str()
7577
} else {
76-
"<error>".to_string()
78+
"<error>"
7779
};
7880

79-
let lineno = if let Ok(x) = vm.to_str(&location_attrs[1]) {
80-
x.value.clone()
81+
let lineno = vm.to_str(&location_attrs[1]);
82+
let lineno = if let Ok(ref x) = lineno {
83+
x.as_str()
8184
} else {
82-
"<error>".to_string()
85+
"<error>"
8386
};
8487

85-
let obj_name = if let Ok(x) = vm.to_str(&location_attrs[2]) {
86-
x.value.clone()
88+
let obj_name = vm.to_str(&location_attrs[2]);
89+
let obj_name = if let Ok(ref x) = obj_name {
90+
x.as_str()
8791
} else {
88-
"<error>".to_string()
92+
"<error>"
8993
};
9094

9195
println!(
@@ -149,17 +153,14 @@ fn exception_args_as_string(
149153
};
150154
vec![args0_repr]
151155
}
152-
_ => {
153-
let mut args_vec = Vec::with_capacity(varargs.elements.len());
154-
for vararg in &varargs.elements {
155-
let arg_repr = match vm.to_repr(vararg) {
156-
Ok(arg_repr) => arg_repr.value.clone(),
157-
Err(_) => "<element repr() failed>".to_string(),
158-
};
159-
args_vec.push(arg_repr);
160-
}
161-
args_vec
162-
}
156+
_ => varargs
157+
.elements
158+
.iter()
159+
.map(|vararg| match vm.to_repr(vararg) {
160+
Ok(arg_repr) => arg_repr.as_str().to_string(),
161+
Err(_) => "<element repr() failed>".to_string(),
162+
})
163+
.collect(),
163164
}
164165
}
165166

vm/src/frame.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ impl Frame {
10581058
.ctx
10591059
.new_function(code_obj, scope, defaults, kw_only_defaults);
10601060

1061-
let name = qualified_name.value.split('.').next_back().unwrap();
1061+
let name = qualified_name.as_str().split('.').next_back().unwrap();
10621062
vm.set_attr(&func_obj, "__name__", vm.new_str(name.to_string()))?;
10631063
vm.set_attr(&func_obj, "__qualname__", qualified_name)?;
10641064
let module = self

vm/src/obj/objbool.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ fn bool_format(
121121
format_spec: PyStringRef,
122122
vm: &VirtualMachine,
123123
) -> PyResult<PyStringRef> {
124-
if format_spec.value.is_empty() {
124+
if format_spec.as_str().is_empty() {
125125
vm.to_str(&obj)
126126
} else {
127127
Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_string()))

vm/src/obj/objbyteinner.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl ByteInnerNewOptions {
104104
if let OptionalArg::Present(enc) = self.encoding {
105105
if let OptionalArg::Present(eval) = self.val_option {
106106
if let Ok(input) = eval.downcast::<PyString>() {
107-
let inner = PyByteInner::from_string(&input.value, enc.as_str(), vm)?;
107+
let inner = PyByteInner::from_string(input.as_str(), enc.as_str(), vm)?;
108108
Ok(inner)
109109
} else {
110110
Err(vm.new_type_error("encoding without a string argument".to_string()))

vm/src/obj/objdict.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl PyDictRef {
156156
for (key, value) in self {
157157
let key_repr = vm.to_repr(&key)?;
158158
let value_repr = vm.to_repr(&value)?;
159-
str_parts.push(format!("{}: {}", key_repr.value, value_repr.value));
159+
str_parts.push(format!("{}: {}", key_repr.as_str(), value_repr.as_str()));
160160
}
161161

162162
format!("{{{}}}", str_parts.join(", "))

vm/src/obj/objfloat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ impl PyFloat {
560560

561561
#[pymethod]
562562
fn fromhex(repr: PyStringRef, vm: &VirtualMachine) -> PyResult<f64> {
563-
hexf_parse::parse_hexf64(&repr.value, false).or_else(|_| match repr.value.as_ref() {
563+
hexf_parse::parse_hexf64(repr.as_str(), false).or_else(|_| match repr.as_str() {
564564
"nan" => Ok(std::f64::NAN),
565565
"inf" => Ok(std::f64::INFINITY),
566566
"-inf" => Ok(std::f64::NEG_INFINITY),

vm/src/obj/objint.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ impl PyInt {
554554

555555
#[pymethod(name = "__format__")]
556556
fn format(&self, spec: PyStringRef, vm: &VirtualMachine) -> PyResult<String> {
557-
let format_spec = FormatSpec::parse(&spec.value);
557+
let format_spec = FormatSpec::parse(spec.as_str());
558558
match format_spec.format_int(&self.value) {
559559
Ok(string) => Ok(string),
560560
Err(err) => Err(vm.new_value_error(err.to_string())),
@@ -593,22 +593,21 @@ impl PyInt {
593593
});
594594
}
595595
}
596-
let x;
597-
if byteorder.value == "big" {
598-
x = match signed {
596+
let x = match byteorder.as_str() {
597+
"big" => match signed {
599598
true => BigInt::from_signed_bytes_be(&bytes.elements),
600599
false => BigInt::from_bytes_be(Sign::Plus, &bytes.elements),
601-
}
602-
} else if byteorder.value == "little" {
603-
x = match signed {
600+
},
601+
"little" => match signed {
604602
true => BigInt::from_signed_bytes_le(&bytes.elements),
605603
false => BigInt::from_bytes_le(Sign::Plus, &bytes.elements),
604+
},
605+
_ => {
606+
return Err(
607+
vm.new_value_error("byteorder must be either 'little' or 'big'".to_string())
608+
)
606609
}
607-
} else {
608-
return Err(
609-
vm.new_value_error("byteorder must be either 'little' or 'big'".to_string())
610-
);
611-
}
610+
};
612611
Ok(x)
613612
}
614613
#[pymethod]
@@ -640,7 +639,7 @@ impl PyInt {
640639
return Err(vm.new_value_error("length parameter is illegal".to_string()));
641640
}
642641

643-
let mut origin_bytes = match byteorder.value.as_str() {
642+
let mut origin_bytes = match byteorder.as_str() {
644643
"big" => match signed {
645644
true => value.to_signed_bytes_be(),
646645
false => value.to_bytes_be().1,
@@ -665,7 +664,7 @@ impl PyInt {
665664
_ => vec![0u8; byte_len - origin_len],
666665
};
667666
let mut bytes = vec![];
668-
match byteorder.value.as_str() {
667+
match byteorder.as_str() {
669668
"big" => {
670669
bytes = append_bytes;
671670
bytes.append(&mut origin_bytes);
@@ -744,7 +743,7 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult<Big
744743

745744
match_class!(match obj.clone() {
746745
string @ PyString => {
747-
let s = string.value.as_str().trim();
746+
let s = string.as_str().trim();
748747
str_to_int(vm, s, base)
749748
}
750749
bytes @ PyBytes => {

vm/src/obj/objlist.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,10 @@ impl PyListRef {
388388

389389
fn repr(self, vm: &VirtualMachine) -> PyResult<String> {
390390
let s = if let Some(_guard) = ReprGuard::enter(self.as_object()) {
391-
let mut str_parts = vec![];
391+
let mut str_parts = Vec::with_capacity(self.elements.borrow().len());
392392
for elem in self.elements.borrow().iter() {
393393
let s = vm.to_repr(elem)?;
394-
str_parts.push(s.value.clone());
394+
str_parts.push(s.as_str().to_string());
395395
}
396396
format!("[{}]", str_parts.join(", "))
397397
} else {
@@ -462,8 +462,8 @@ impl PyListRef {
462462
return Ok(index);
463463
}
464464
}
465-
let needle_str = &vm.to_str(&needle)?.value;
466-
Err(vm.new_value_error(format!("'{}' is not in list", needle_str)))
465+
let needle_str = vm.to_str(&needle)?;
466+
Err(vm.new_value_error(format!("'{}' is not in list", needle_str.as_str())))
467467
}
468468

469469
fn pop(self, i: OptionalArg<isize>, vm: &VirtualMachine) -> PyResult {
@@ -499,8 +499,8 @@ impl PyListRef {
499499
self.elements.borrow_mut().remove(index);
500500
Ok(())
501501
} else {
502-
let needle_str = &vm.to_str(&needle)?.value;
503-
Err(vm.new_value_error(format!("'{}' is not in list", needle_str)))
502+
let needle_str = vm.to_str(&needle)?;
503+
Err(vm.new_value_error(format!("'{}' is not in list", needle_str.as_str())))
504504
}
505505
}
506506

vm/src/obj/objnone.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl PyNoneRef {
6868
}
6969
}
7070

71-
if let Some(attr) = class_get_attr(&cls, &name.value) {
71+
if let Some(attr) = class_get_attr(&cls, name.as_str()) {
7272
let attr_class = attr.class();
7373
if class_has_attr(&attr_class, "__set__") {
7474
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
@@ -84,10 +84,10 @@ impl PyNoneRef {
8484
}
8585

8686
// None has no attributes and cannot have attributes set on it.
87-
// if let Some(obj_attr) = self.as_object().get_attr(&name.value) {
87+
// if let Some(obj_attr) = self.as_object().get_attr(name.as_str()) {
8888
// Ok(obj_attr)
8989
// } else
90-
if let Some(attr) = class_get_attr(&cls, &name.value) {
90+
if let Some(attr) = class_get_attr(&cls, name.as_str()) {
9191
let attr_class = attr.class();
9292
if let Some(get_func) = class_get_attr(&attr_class, "__get__") {
9393
call_descriptor(attr, get_func, self.into_object(), cls.into_object(), vm)

0 commit comments

Comments
 (0)