Skip to content

Commit 49af908

Browse files
yonmilkyouknowone
authored andcommitted
Fix warning warn_explicit
1 parent eb27d1e commit 49af908

File tree

3 files changed

+50
-52
lines changed

3 files changed

+50
-52
lines changed

vm/src/builtins/dict.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ impl PyDict {
288288
}
289289

290290
#[pymethod]
291-
fn clear(&self) {
291+
pub fn clear(&self) {
292292
self.entries.clear()
293293
}
294294

vm/src/vm/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ declare_const_name! {
213213
keys,
214214
items,
215215
values,
216+
version,
216217
update,
217218
copy,
218219
flush,

vm/src/warn.rs

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use itertools::Itertools;
2-
31
use crate::{
42
builtins::{PyDict, PyDictRef, PyListRef, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef},
5-
convert::TryFromObject,
3+
convert::{IntoObject, TryFromObject},
64
AsObject, Context, Py, PyObjectRef, PyResult, VirtualMachine,
75
};
86

@@ -104,42 +102,43 @@ fn get_filter(
104102
fn already_warned(
105103
registry: PyObjectRef,
106104
key: PyObjectRef,
107-
should_set: usize,
105+
should_set: bool,
108106
vm: &VirtualMachine,
109-
) -> bool {
110-
let version_obj = registry.get_item("version", vm).ok();
111-
let filters_version = vm
112-
.ctx
113-
.new_int(vm.state.warnings.filters_version)
114-
.as_object()
115-
.to_owned();
107+
) -> PyResult<bool> {
108+
let version_obj = registry.get_item(identifier!(&vm.ctx, version), vm).ok();
109+
let filters_version = vm.ctx.new_int(vm.state.warnings.filters_version).into();
116110

117-
if version_obj.is_none()
118-
|| version_obj.as_ref().unwrap().try_int(vm).is_err()
119-
|| !version_obj.unwrap().is(&filters_version)
120-
{
121-
let registry = registry.dict();
122-
registry.as_ref().map(|registry| {
123-
registry.into_iter().collect_vec().clear();
124-
registry
125-
});
111+
match version_obj {
112+
Some(version_obj)
113+
if version_obj.try_int(vm).is_ok() || version_obj.is(&filters_version) =>
114+
{
115+
let already_warned = registry.get_item(key.as_ref(), vm)?;
116+
if already_warned.is_true(vm)? {
117+
return Ok(true);
118+
}
119+
}
120+
_ => {
121+
let registry = registry.dict();
122+
registry.as_ref().map(|registry| {
123+
registry.clear();
124+
registry
125+
});
126126

127-
if let Some(registry) = registry {
128-
if registry.set_item("version", filters_version, vm).is_err() {
129-
return false;
127+
if let Some(registry) = registry {
128+
if registry.set_item("version", filters_version, vm).is_err() {
129+
return Ok(false);
130+
}
130131
}
131132
}
132-
} else {
133-
let already_warned = registry.get_item(key.as_ref(), vm);
134-
return already_warned.is_ok();
135133
}
136134

137135
/* This warning wasn't found in the registry, set it. */
138-
if should_set != 0 {
139-
registry.set_item(key.as_ref(), vm.new_pyobj(""), vm).ok();
140-
}
141-
142-
false
136+
Ok(if should_set {
137+
let item = vm.ctx.true_value.clone().into();
138+
registry.set_item(key.as_ref(), item, vm).map(|_| true)?
139+
} else {
140+
false
141+
})
143142
}
144143

145144
fn normalize_module(filename: PyStrRef, vm: &VirtualMachine) -> Option<PyObjectRef> {
@@ -148,7 +147,7 @@ fn normalize_module(filename: PyStrRef, vm: &VirtualMachine) -> Option<PyObjectR
148147
if len == 0 {
149148
Some(vm.new_pyobj("<unknown>"))
150149
} else if len >= 3 && filename.as_str().contains(".py") {
151-
Some(vm.new_pyobj(filename.as_str().replace(".py", "")))
150+
Some(vm.new_pyobj(&filename.as_str()[..len - 3]))
152151
} else {
153152
Some(filename.as_object().to_owned())
154153
}
@@ -166,26 +165,16 @@ fn warn_explicit(
166165
_source: Option<PyObjectRef>,
167166
vm: &VirtualMachine,
168167
) -> PyResult<()> {
169-
if registry.clone().is_true(vm)?
170-
&& !registry.class().is(vm.ctx.types.dict_type)
171-
&& !registry.class().is(vm.ctx.types.none_type)
172-
{
173-
return Err(vm.new_type_error("'registry' must be a dict or None".to_string()));
174-
}
168+
let registry: PyObjectRef = registry
169+
.try_into_value(vm)
170+
.map_err(|_| vm.new_type_error("'registry' must be a dict or None".to_owned()))?;
175171

176172
// Normalize module.
177-
let module = module.and(normalize_module(filename, vm));
178-
let module = if let Some(module) = module {
179-
module
180-
} else {
181-
return Ok(());
173+
let module = match module.or_else(|| normalize_module(filename, vm)) {
174+
Some(module) => module,
175+
None => return Ok(()),
182176
};
183177

184-
// Normalize message.
185-
let text = message.as_str();
186-
if text.is_empty() {
187-
return Ok(());
188-
}
189178
let category = if let Some(category) = category {
190179
if !category.fast_issubclass(vm.ctx.exceptions.warning) {
191180
return Err(vm.new_type_error(format!(
@@ -198,26 +187,34 @@ fn warn_explicit(
198187
vm.ctx.exceptions.user_warning.to_owned()
199188
};
200189

190+
// Normalize message.
191+
let (category, text) = if message.fast_isinstance(vm.ctx.exceptions.warning) {
192+
(message.class().into_owned(), message.as_object().str(vm)?)
193+
} else {
194+
(category, message)
195+
};
196+
201197
// Create key.
202198
let key = PyTuple::new_ref(
203199
vec![
204200
vm.ctx.new_int(3).into(),
205-
vm.ctx.new_str(text).into(),
201+
vm.ctx.new_str(text.as_str()).into(),
206202
category.as_object().to_owned(),
207203
vm.ctx.new_int(lineno).into(),
208204
],
209205
&vm.ctx,
210206
);
211207

212-
if already_warned(registry, key.as_object().to_owned(), 0, vm) {
208+
if !vm.is_none(registry.as_object()) && already_warned(registry, key.into_object(), false, vm)?
209+
{
213210
return Ok(());
214211
}
215212
// Else this warning hasn't been generated before.
216213

217214
let item = vm.ctx.new_tuple(vec![]).into();
218215
let _action = get_filter(
219216
category.as_object().to_owned(),
220-
vm.ctx.new_str(text).into(),
217+
vm.ctx.new_str(text.as_str()).into(),
221218
lineno,
222219
module,
223220
item,

0 commit comments

Comments
 (0)