Repository: Qiskit/qiskit

Issue:
ghz example is failing in qobj
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**:
- **Python version**:
- **Operating system**:

### What is the current behavior?



### Steps to reproduce the problem



### What is the expected behavior?
```
>>> python examples/python/ghz.py
```

```
Traceback (most recent call last):
  File "examples/python/ghz.py", line 59, in <module>
    result = job.result()
  File "/anaconda3/lib/python3.6/site-packages/qiskit/providers/ibmq/ibmqjob.py", line 186, in result
    job_response = self._wait_for_result(timeout=timeout, wait=wait)
  File "/anaconda3/lib/python3.6/site-packages/qiskit/providers/ibmq/ibmqjob.py", line 190, in _wait_for_result
    self._wait_for_submission(timeout)
  File "/anaconda3/lib/python3.6/site-packages/qiskit/providers/ibmq/ibmqjob.py", line 391, in _wait_for_submission
    raise self._future_captured_exception
  File "/anaconda3/lib/python3.6/site-packages/qiskit/providers/ibmq/ibmqjob.py", line 330, in _submit_callback
    submit_info = self._api.run_job(self._qobj_payload, backend_name=backend_name)
  File "/anaconda3/lib/python3.6/site-packages/qiskit/providers/ibmq/api/ibmqconnector.py", line 144, in run_job
    job = self.req.post(url, data=json.dumps(data))
  File "/anaconda3/lib/python3.6/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/anaconda3/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/anaconda3/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/anaconda3/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'Zero' is not JSON serializable
```

Not sure what is causing this serialization error. @diego-plan9 can you take a look?


Discussion:
It seems quite similar to the errors in Aer that caused two tests to be skipped during the Qobj PR (as `IBMQProvider` contains also code very similar to Aer's to deal with noise model, etc) - I'll check with @chriseclectic as they can probably be handled at the same time.
a few other examples also fail. it seems the failure happens when trying to run on devices, not Aer.
Seems we are being too lax when handling `qobj.experiment.instructions.parameters`, and is rippling up when using types that cannot be serialized by default - will issue a PR shortly!

Resolving patch:
diff --git a/qiskit/qobj/models.py b/qiskit/qobj/models.py
--- a/qiskit/qobj/models.py
+++ b/qiskit/qobj/models.py
@@ -10,7 +10,8 @@
 from marshmallow.validate import Length, Range, Regexp
 
 from qiskit.validation.base import BaseModel, BaseSchema, bind_schema
-from qiskit.validation.fields import Integer, List, Nested, Raw, String
+from qiskit.validation.fields import (Integer, List, Nested, String,
+                                      InstructionParameter)
 
 
 class QobjConditionalSchema(BaseSchema):
@@ -31,7 +32,7 @@ class QobjInstructionSchema(BaseSchema):
     # Optional properties.
     qubits = List(Integer(validate=Range(min=0)),
                   validate=Length(min=1))
-    params = List(Raw())
+    params = List(InstructionParameter())
     memory = List(Integer(validate=Range(min=0)),
                   validate=Length(min=1))
     conditional = Nested(QobjConditionalSchema)
diff --git a/qiskit/validation/fields/__init__.py b/qiskit/validation/fields/__init__.py
--- a/qiskit/validation/fields/__init__.py
+++ b/qiskit/validation/fields/__init__.py
@@ -12,8 +12,8 @@
     1. Distinguish a new type, like the ``Complex`` number in this module.
     2. Use a new Marshmallow field not used in ``qiskit`` yet.
 
-Marshamallow fields does not allow model validation so you need to create a new
-field, make it subclass of the Marshamallow field *and* ``ModelTypeValidator``,
+Marshmallow fields does not allow model validation so you need to create a new
+field, make it subclass of the Marshmallow field *and* ``ModelTypeValidator``,
 and redefine ``valid_types`` to be the list of valid types. Usually, **the
 same types this field deserializes to**. For instance::
 
@@ -24,45 +24,16 @@ class Boolean(marshmallow.fields.Boolean, ModelTypeValidator):
 
 See ``ModelTypeValidator`` for more subclassing options.
 """
+
 from datetime import date, datetime
 
 from marshmallow import fields as _fields
-from marshmallow.utils import is_collection
 
 from qiskit.validation import ModelTypeValidator
 from qiskit.validation.fields.polymorphic import ByAttribute, ByType, TryFrom
 from qiskit.validation.fields.containers import Nested, List
 
-
-class Complex(ModelTypeValidator):
-    """Field for complex numbers.
-
-    Field for parsing complex numbers:
-    * deserializes to Python's `complex`.
-    * serializes to a tuple of 2 decimals `(real, imaginary)`
-    """
-
-    valid_types = (complex, )
-
-    default_error_messages = {
-        'invalid': '{input} cannot be parsed as a complex number.',
-        'format': '"{input}" cannot be formatted as complex number.',
-    }
-
-    def _serialize(self, value, attr, obj):
-        try:
-            return [value.real, value.imag]
-        except AttributeError:
-            self.fail('format', input=value)
-
-    def _deserialize(self, value, attr, data):
-        if not is_collection(value) or len(value) != 2:
-            self.fail('invalid', input=value)
-
-        try:
-            return complex(*value)
-        except (ValueError, TypeError):
-            self.fail('invalid', input=value)
+from .custom import Complex, InstructionParameter
 
 
 class String(_fields.String, ModelTypeValidator):
diff --git a/qiskit/validation/fields/custom.py b/qiskit/validation/fields/custom.py
new file mode 100644
--- /dev/null
+++ b/qiskit/validation/fields/custom.py
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2019, IBM.
+#
+# This source code is licensed under the Apache License, Version 2.0 found in
+# the LICENSE.txt file in the root directory of this source tree.
+
+"""Fields custom to Terra to be used with Qiskit validated classes."""
+
+import numpy
+import sympy
+
+from marshmallow.utils import is_collection
+
+from qiskit.validation import ModelTypeValidator
+
+
+class Complex(ModelTypeValidator):
+    """Field for complex numbers.
+
+    Field for parsing complex numbers:
+    * deserializes to Python's `complex`.
+    * serializes to a tuple of 2 decimals `(real, imaginary)`
+    """
+
+    valid_types = (complex, )
+
+    default_error_messages = {
+        'invalid': '{input} cannot be parsed as a complex number.',
+        'format': '"{input}" cannot be formatted as complex number.',
+    }
+
+    def _serialize(self, value, attr, obj):
+        try:
+            return [value.real, value.imag]
+        except AttributeError:
+            self.fail('format', input=value)
+
+    def _deserialize(self, value, attr, data):
+        if not is_collection(value) or len(value) != 2:
+            self.fail('invalid', input=value)
+
+        try:
+            return complex(*value)
+        except (ValueError, TypeError):
+            self.fail('invalid', input=value)
+
+
+class InstructionParameter(ModelTypeValidator):
+    """Field for objects used in instruction parameters.
+
+    This field provides support for parsing objects of types that uses by
+    qobj.experiments.instructions.parameters:
+    * basic Python types: complex, int, float, str
+    * ``numpy``: integer, float
+    * ``sympy``: Symbol, Basic
+
+    Note that by using this field, serialization-deserialization round-tripping
+    becomes not possible, as certain types serialize to the same Python basic
+    type (for example, numpy.float and regular float). If possible, it is
+    recommended that more specific and defined fields are used instead.
+    """
+    valid_types = (complex, int, float, str,
+                   numpy.integer, numpy.float, sympy.Basic, sympy.Symbol)
+
+    def _serialize(self, value, attr, obj):
+        # pylint: disable=too-many-return-statements
+        if isinstance(value, (float, int, str)):
+            return value
+        if isinstance(value, complex):
+            return [value.real, value.imag]
+        if isinstance(value, numpy.integer):
+            return int(value)
+        if isinstance(value, numpy.float):
+            return float(value)
+        if isinstance(value, sympy.Symbol):
+            return str(value)
+        if isinstance(value, sympy.Basic):
+            if value.is_imaginary:
+                return [float(sympy.re(value)), float(sympy.im(value))]
+            else:
+                return float(value.evalf())
+
+        return self.fail('invalid', input=value)
+
+    def _deserialize(self, value, attr, data):
+        if is_collection(value) and len(value) != 2:
+            return complex(*value)
+
+        return value


Test patch:
diff --git a/test/python/aer_provider_integration_test/test_extensions_simulator.py b/test/python/aer_provider_integration_test/test_extensions_simulator.py
--- a/test/python/aer_provider_integration_test/test_extensions_simulator.py
+++ b/test/python/aer_provider_integration_test/test_extensions_simulator.py
@@ -26,7 +26,6 @@ class TestExtensionsSimulator(QiskitTestCase):
     """
     _desired_fidelity = 0.99
 
-    @unittest.expectedFailure
     def test_snapshot(self):
         """snapshot a bell state in the middle of circuit"""
         basis_gates = ['cx', 'u1', 'u2', 'u3', 'snapshot']
diff --git a/test/python/aer_provider_integration_test/test_qasm_simulator.py b/test/python/aer_provider_integration_test/test_qasm_simulator.py
--- a/test/python/aer_provider_integration_test/test_qasm_simulator.py
+++ b/test/python/aer_provider_integration_test/test_qasm_simulator.py
@@ -78,7 +78,6 @@ def test_if_statement(self):
         self.assertEqual(counts_if_true, {'111': 100})
         self.assertEqual(counts_if_false, {'001': 100})
 
-    @unittest.expectedFailure
     def test_teleport(self):
         """test teleportation as in tutorials"""
         self.log.info('test_teleport')