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
18 changes: 16 additions & 2 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,7 @@ def test_traceback_and_frame_types(self):
self.assertIsInstance(exc.__traceback__, types.TracebackType)
self.assertIsInstance(exc.__traceback__.tb_frame, types.FrameType)

# XXX: RUSTPYTHON
@unittest.skipUnless(_datetime, "requires _datetime module")
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'NoneType' object has no attribute 'datetime_CAPI'
def test_capsule_type(self):
self.assertIsInstance(_datetime.datetime_CAPI, types.CapsuleType)

Expand Down Expand Up @@ -2127,6 +2126,21 @@ class Spam(types.SimpleNamespace):
self.assertIs(type(spam2), Spam)
self.assertEqual(vars(spam2), {'ham': 5, 'eggs': 9})

def test_replace_invalid_subtype(self):
# See https://github.com/python/cpython/issues/143636.
class MyNS(types.SimpleNamespace):
def __new__(cls, *args, **kwargs):
if created:
return 12345
return super().__new__(cls)

created = False
ns = MyNS()
created = True
err = (r"^expect types\.SimpleNamespace type, "
r"but .+\.MyNS\(\) returned 'int' object")
self.assertRaisesRegex(TypeError, err, copy.replace, ns)

def test_fake_namespace_compare(self):
# Issue #24257: Incorrect use of PyObject_IsInstance() caused
# SystemError.
Expand Down
15 changes: 15 additions & 0 deletions crates/vm/src/builtins/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ impl PyNamespace {
let cls: PyObjectRef = zelf.class().to_owned().into();
let result = cls.call((), vm)?;

if !zelf.class().is(result.class()) {
return Err(vm.new_type_error(format!(
"expect {} type, but {}() returned '{}' object",
Self::class(&vm.ctx).slot_name(),
Comment thread
coderabbitai[bot] marked this conversation as resolved.
zelf.class()
.__qualname__(vm)
.downcast_ref::<PyStr>()
.map_or_else(
|| zelf.class().name().to_string(),
|n| n.as_wtf8().to_string()
),
result.class().name(),
)));
}

// Copy the current namespace dict to the new instance
let src_dict = zelf.dict().unwrap();
let dst_dict = result.dict().unwrap();
Expand Down
Loading