diff --git a/pymbolic/mapper/__init__.py b/pymbolic/mapper/__init__.py index 5303c789631506c7cc0ff57b60d894742e737028..2536de17f2565b8dd0f32f2236314364a0b7fd35 100644 --- a/pymbolic/mapper/__init__.py +++ b/pymbolic/mapper/__init__.py @@ -231,7 +231,10 @@ class CachedMapper(Mapper): *self* does not store any mutable state. Derived mappers must override this method. """ - return (expr, args, tuple(sorted(kwargs.items()))) + # Must add 'type(expr)', to differentiate between python scalar types. + # In Python, the following conditions are true: "hash(4) == hash(4.0)" + # and "4 == 4.0", but their traversal results cannot be re-used. + return (type(expr), expr, args, tuple(sorted(kwargs.items()))) def __call__(self, expr, *args, **kwargs): cache_key = self.get_cache_key(expr, *args, **kwargs) diff --git a/test/test_pymbolic.py b/test/test_pymbolic.py index 18e6cefc2c07ef8bfe614076be5f5728e101f98b..08a9d81cd24fe52dbc147ec561d2ca4e952e7510 100644 --- a/test/test_pymbolic.py +++ b/test/test_pymbolic.py @@ -925,6 +925,16 @@ def test_cached_mapper_memoizes(): # }}} + +def test_cached_mapper_differentiates_float_int(): + # pymbolic.git<=d343cf14 failed this regression. + from pymbolic.mapper import CachedIdentityMapper + expr = prim.Sum((4, 4.0)) + cached_mapper = CachedIdentityMapper() + new_expr = cached_mapper(expr) + assert isinstance(new_expr.children[0], int) + assert isinstance(new_expr.children[1], float) + # }}}