From 2466bc3a9a692f374c3e1cc699b65d3b82d636bf Mon Sep 17 00:00:00 2001 From: Victory Omole Date: Thu, 5 Aug 2021 01:45:01 -0500 Subject: [PATCH] Throw `TypeError` around `any` call in `if hasattr(obj, '__iter__') and not isinstance(obj, str):` to deal with a numpy special case (#4382) This `TypeError` is thrown from the `numpy` source: https://github.com/numpy/numpy/blob/ffcf508951f646c2ae02c2a0583b884f7a9163e8/numpy/core/src/multiarray/arrayobject.c#L1700-L1702 Fixes: https://github.com/quantumlib/Cirq/issues/4030 --- cirq-core/cirq/protocols/json_serialization.py | 9 ++++++++- cirq-core/cirq/protocols/json_serialization_test.py | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cirq-core/cirq/protocols/json_serialization.py b/cirq-core/cirq/protocols/json_serialization.py index 4a8b7b13830..e89a9e81c47 100644 --- a/cirq-core/cirq/protocols/json_serialization.py +++ b/cirq-core/cirq/protocols/json_serialization.py @@ -442,8 +442,15 @@ def has_serializable_by_keys(obj: Any) -> bool: # Handle primitive container types. if isinstance(obj, Dict): return any(has_serializable_by_keys(elem) for pair in obj.items() for elem in pair) + if hasattr(obj, '__iter__') and not isinstance(obj, str): - return any(has_serializable_by_keys(elem) for elem in obj) + # Return False on TypeError because some numpy values + # (like np.array(1)) have iterable methods + # yet return a TypeError when there is an attempt to iterate over them + try: + return any(has_serializable_by_keys(elem) for elem in obj) + except TypeError: + return False return False diff --git a/cirq-core/cirq/protocols/json_serialization_test.py b/cirq-core/cirq/protocols/json_serialization_test.py index 93fe6a2f93d..c10ace300a4 100644 --- a/cirq-core/cirq/protocols/json_serialization_test.py +++ b/cirq-core/cirq/protocols/json_serialization_test.py @@ -796,3 +796,12 @@ def custom_resolver(name): return QuantumVolumeParams assert_json_roundtrip_works(qvp, resolvers=[custom_resolver] + cirq.DEFAULT_RESOLVERS) + + +def test_numpy_values(): + assert ( + cirq.to_json({'value': np.array(1)}) + == """{ + "value": 1 +}""" + )