Skip to content

Commit 3990378

Browse files
authored
Merge pull request #1147 from codeflash-ai/mappingcheck
support MappingProxyType
2 parents 5e61a8b + 67ece97 commit 3990378

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

codeflash/verification/comparator.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ def comparator(orig: Any, new: Any, superset_obj=False) -> bool: # noqa: ANN001
257257
return False
258258
return True
259259

260+
# Handle mappingproxy (read-only dict view, commonly seen as class.__dict__)
261+
if isinstance(orig, types.MappingProxyType):
262+
return comparator(dict(orig), dict(new), superset_obj)
263+
260264
# Handle dict view types (dict_keys, dict_values, dict_items)
261265
# Use type name checking since these are not directly importable types
262266
type_name = type(orig).__name__

tests/test_comparator.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,77 @@ def test_dict_views() -> None:
23162316
assert not comparator(d.items(), [("a", 1), ("b", 2)])
23172317

23182318

2319+
def test_mappingproxy() -> None:
2320+
"""Test comparator support for types.MappingProxyType (read-only dict view)."""
2321+
import types
2322+
2323+
# Basic equality
2324+
mp1 = types.MappingProxyType({"a": 1, "b": 2, "c": 3})
2325+
mp2 = types.MappingProxyType({"a": 1, "b": 2, "c": 3})
2326+
assert comparator(mp1, mp2)
2327+
2328+
# Different values
2329+
mp3 = types.MappingProxyType({"a": 1, "b": 2, "c": 4})
2330+
assert not comparator(mp1, mp3)
2331+
2332+
# Different keys
2333+
mp4 = types.MappingProxyType({"a": 1, "b": 2, "d": 3})
2334+
assert not comparator(mp1, mp4)
2335+
2336+
# Different length
2337+
mp5 = types.MappingProxyType({"a": 1, "b": 2})
2338+
assert not comparator(mp1, mp5)
2339+
2340+
# Order doesn't matter (like dict)
2341+
mp6 = types.MappingProxyType({"c": 3, "a": 1, "b": 2})
2342+
assert comparator(mp1, mp6)
2343+
2344+
# Empty mappingproxy
2345+
empty1 = types.MappingProxyType({})
2346+
empty2 = types.MappingProxyType({})
2347+
assert comparator(empty1, empty2)
2348+
2349+
# Nested values
2350+
nested1 = types.MappingProxyType({"a": [1, 2, 3], "b": {"x": 1}})
2351+
nested2 = types.MappingProxyType({"a": [1, 2, 3], "b": {"x": 1}})
2352+
nested3 = types.MappingProxyType({"a": [1, 2, 4], "b": {"x": 1}})
2353+
assert comparator(nested1, nested2)
2354+
assert not comparator(nested1, nested3)
2355+
2356+
# mappingproxy is not equal to dict (different types)
2357+
d = {"a": 1, "b": 2}
2358+
mp = types.MappingProxyType({"a": 1, "b": 2})
2359+
assert not comparator(mp, d)
2360+
assert not comparator(d, mp)
2361+
2362+
# Verify class __dict__ is indeed a mappingproxy
2363+
class MyClass:
2364+
x = 1
2365+
y = 2
2366+
2367+
assert isinstance(MyClass.__dict__, types.MappingProxyType)
2368+
2369+
2370+
def test_mappingproxy_superset() -> None:
2371+
"""Test comparator superset_obj support for mappingproxy."""
2372+
import types
2373+
2374+
mp1 = types.MappingProxyType({"a": 1, "b": 2})
2375+
mp2 = types.MappingProxyType({"a": 1, "b": 2, "c": 3})
2376+
2377+
# mp2 is a superset of mp1
2378+
assert comparator(mp1, mp2, superset_obj=True)
2379+
# mp1 is not a superset of mp2
2380+
assert not comparator(mp2, mp1, superset_obj=True)
2381+
2382+
# Same mappingproxy with superset_obj=True
2383+
assert comparator(mp1, mp1, superset_obj=True)
2384+
2385+
# Different values even with superset
2386+
mp3 = types.MappingProxyType({"a": 1, "b": 99, "c": 3})
2387+
assert not comparator(mp1, mp3, superset_obj=True)
2388+
2389+
23192390
def test_tensorflow_tensor() -> None:
23202391
"""Test comparator support for TensorFlow Tensor objects."""
23212392
try:

0 commit comments

Comments
 (0)