Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/vm/src/stdlib/_warnings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fn warn(
mod _warnings {
use crate::{
AsObject, PyObject, PyObjectRef, PyResult, VirtualMachine,
builtins::{PyDictRef, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
builtins::{PyDict, PyDictRef, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
convert::TryFromObject,
function::OptionalArg,
};
Expand Down Expand Up @@ -180,7 +180,7 @@ mod _warnings {
let source_line = if let Some(mg) = args.module_globals.into_option() {
if vm.is_none(&mg) {
None
} else if !mg.class().is(vm.ctx.types.dict_type) {
} else if mg.downcast_ref::<PyDict>().is_none() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will be affected by frozendict. let's keep it later to 3.15

return Err(vm.new_type_error(format!(
"module_globals must be a dict, not '{}'",
mg.class().name()
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/warn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ pub(crate) fn get_source_line(
};

let module_name = if let Some(dict) = module_globals.downcast_ref::<PyDict>() {
match dict.get_item_opt(identifier!(vm, __name__), vm)? {
match dict.inner_getitem_opt(identifier!(vm, __name__), vm)? {
Some(name) => name,
None => return Ok(None),
}
Expand Down
47 changes: 47 additions & 0 deletions extra_tests/snippets/stdlib_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,50 @@ class CustomWarning(UserWarning):
assert len(caught) == 1
assert caught[0].message is message
assert caught[0].category is CustomWarning


from importlib.machinery import ModuleSpec

events = []


class WarningLoader:
def get_source(self, name):
events.append(("source", name))
return "source line\n"


class WarningGlobals(dict):
def get(self, key, default=None):
events.append(("get", key))
return super().get(key, default)

def __getitem__(self, key):
raise AssertionError("module name must use stored dict lookup")

__missing__ = __getitem__


loader = WarningLoader()
module_globals = WarningGlobals(
__name__="stored_name",
__loader__=loader,
__spec__=ModuleSpec("stored_name", loader),
)
for has_name in (True, False):
events.clear()
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
warnings.warn_explicit(
"subclass globals",
UserWarning,
"fixed_ascii.py",
1,
module_globals=module_globals,
)
assert len(caught) == 1
expected = [("get", "__loader__"), ("get", "__spec__")]
if has_name:
expected.append(("source", "stored_name"))
del module_globals["__name__"]
assert events == expected
Loading