Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
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
83 changes: 83 additions & 0 deletions 83 tests/snippets/dict_union.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

import testutils

def test_dunion_ior0():
a={1:2,2:3}
b={3:4,5:6}
a|=b

assert a == {1:2,2:3,3:4,5:6}, f"wrong value assigned {a=}"
assert b == {3:4,5:6}, f"right hand side modified, {b=}"

def test_dunion_or0():
a={1:2,2:3}
b={3:4,5:6}
c=a|b

assert a == {1:2,2:3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3:4,5:6}, f"right hand side of non-assignment operator modified, {b=}"
assert c == {1:2,2:3, 3:4, 5:6}, f"unexpected result of dict union {c=}"


def test_dunion_or1():
a={1:2,2:3}
b={3:4,5:6}
c=a.__or__(b)

assert a == {1:2,2:3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3:4,5:6}, f"right hand side of non-assignment operator modified, {b=}"
assert c == {1:2,2:3, 3:4, 5:6}, f"unexpected result of dict union {c=}"


def test_dunion_ror0():
a={1:2,2:3}
b={3:4,5:6}
c=b.__ror__(a)

assert a == {1:2,2:3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3:4,5:6}, f"right hand side of non-assignment operator modified, {b=}"
assert c == {1:2,2:3, 3:4, 5:6}, f"unexpected result of dict union {c=}"


def test_dunion_other_types():
def perf_test_or(other_obj):
d={1:2}
try:
d.__or__(other_obj)
except:
return True
return False

def perf_test_ior(other_obj):
d={1:2}
try:
d.__ior__(other_obj)
except:
return True
return False

def perf_test_ror(other_obj):
d={1:2}
try:
d.__ror__(other_obj)
except:
return True
return False

test_fct={'__or__':perf_test_or, '__ror__':perf_test_ror, '__ior__':perf_test_ior}
others=['FooBar', 42, [36], set([19]), ['aa'], None]
for tfn,tf in test_fct.items():
for other in others:
assert tf(other), f"Failed: dict {tfn}, accepted {other}"




testutils.skip_if_unsupported(3,9,test_dunion_ior0)
testutils.skip_if_unsupported(3,9,test_dunion_or0)
testutils.skip_if_unsupported(3,9,test_dunion_or1)
testutils.skip_if_unsupported(3,9,test_dunion_ror0)
testutils.skip_if_unsupported(3,9,test_dunion_other_types)



26 changes: 26 additions & 0 deletions 26 tests/snippets/testutils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import platform
import sys

def assert_raises(expected, *args, _msg=None, **kw):
if args:
f, f_args = args[0], args[1:]
Expand Down Expand Up @@ -67,3 +70,26 @@ def assert_isinstance(obj, klass):

def assert_in(a, b):
_assert_print(lambda: a in b, [a, 'in', b])

def skip_if_unsupported(req_maj_vers, req_min_vers, test_fct):
def exec():
test_fct()

if platform.python_implementation() == 'RustPython':
exec()
elif sys.version_info.major>=req_maj_vers and sys.version_info.minor>=req_min_vers:
exec()
else:
print(f'Skipping test as a higher python version is required. Using {platform.python_implementation()} {platform.python_version()}')

def fail_if_unsupported(req_maj_vers, req_min_vers, test_fct):
def exec():
test_fct()

if platform.python_implementation() == 'RustPython':
exec()
elif sys.version_info.major>=req_maj_vers and sys.version_info.minor>=req_min_vers:
exec()
else:
assert False, f'Test cannot performed on this python version. {platform.python_implementation()} {platform.python_version()}'

43 changes: 43 additions & 0 deletions 43 vm/src/obj/objdict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ impl PyDictRef {
Ok(())
}

fn merge_dict(
dict: &DictContentType,
dict_other: PyDictRef,
vm: &VirtualMachine,
) -> PyResult<()> {
for (key, value) in dict_other {
dict.insert(vm, &key, value)?;
}
Ok(())
}

#[pyclassmethod]
fn fromkeys(
class: PyClassRef,
Expand Down Expand Up @@ -320,6 +331,38 @@ impl PyDictRef {
PyDictRef::merge(&self.entries, dict_obj, kwargs, vm)
}

#[pymethod(name = "__ior__")]
fn ior(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
let dicted: Result<PyDictRef, _> = other.clone().downcast();
if let Ok(other) = dicted {
PyDictRef::merge_dict(&self.entries, other, vm)?;
return Ok(self.into_object());
}
Err(vm.new_type_error("__ior__ not implemented for non-dict type".to_owned()))
}

#[pymethod(name = "__ror__")]
fn ror(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDict> {
let dicted: Result<PyDictRef, _> = other.clone().downcast();
if let Ok(other) = dicted {
let other_cp = other.copy();
PyDictRef::merge_dict(&other_cp.entries, self, vm)?;
return Ok(other_cp);
}
Err(vm.new_type_error("__ror__ not implemented for non-dict type".to_owned()))
}

#[pymethod(name = "__or__")]
fn or(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDict> {
let dicted: Result<PyDictRef, _> = other.clone().downcast();
if let Ok(other) = dicted {
let self_cp = self.copy();
PyDictRef::merge_dict(&self_cp.entries, other, vm)?;
return Ok(self_cp);
}
Err(vm.new_type_error("__or__ not implemented for non-dict type".to_owned()))
}

#[pymethod]
fn pop(
self,
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.