Repository: PlasmaPy/PlasmaPy

Issue:
Make call_string work with Quantity objects
The [`call_string`](https://github.com/PlasmaPy/PlasmaPy/blob/28156768b242564265e33b3baf8ae231f1a7c166/plasmapy/utils/pytest_helpers.py#L82) function in `utils` is designed to return a string of a function call, which is often really useful to put into error messages.  An example is:
```Python
>>> from plasmapy.utils import call_string
>>> def f(x, y=2): return x + y
>>> call_string(f, 1, {'y': 2})
'f(1, y=2)'
```
However, `call_string` does not work so well with Quantity objects:
```Python
>>> import astropy.units as u
>>> call_string(f, 5 * u.m)
'f(<Quantity 5. m>)'
```
Since we generally do `import astropy.units as u`, we probably should make `call_string` behave like this:
```Python
>>> call_string(f, 5 * u.m)
'f(5 * u.m)'
```
This is very related to #331.  Thanks!


Discussion:

Resolving patch:
diff --git a/plasmapy/classes/plasma.py b/plasmapy/classes/plasma.py
--- a/plasmapy/classes/plasma.py
+++ b/plasmapy/classes/plasma.py
@@ -23,6 +23,8 @@
                              integer_charge,
                              )
 
+from plasmapy.utils import call_string
+
 class Plasma3D():
     """
     Core class for describing and calculating plasma parameters with
@@ -133,7 +135,7 @@ def __str__(self):
         Examples
         --------
         >>> print(PlasmaBlob(1e4*u.K, 1e20/u.m**3, particle='p'))
-        PlasmaBlob(T_e=10000.0 K, n_e=1e+20 1 / m3, particle=p, Z=1)
+        PlasmaBlob(T_e=10000.0*u.K, n_e=1e+20*u.m**-3, particle='p', Z=1)
         Intermediate coupling regime: Gamma = 0.012502837623108332.
         Thermal kinetic energy dominant: Theta = 109690.53176225389
 
@@ -151,9 +153,14 @@ def __repr__(self):
         --------
         >>> from astropy import units as u
         >>> PlasmaBlob(1e4*u.K, 1e20/u.m**3, particle='p')
-        PlasmaBlob(T_e=10000.0 K, n_e=1e+20 1 / m3, particle=p, Z=1)
+        PlasmaBlob(T_e=10000.0*u.K, n_e=1e+20*u.m**-3, particle='p', Z=1)
         """
-        return f"PlasmaBlob(T_e={self.T_e}, n_e={self.n_e}, particle={self.particle}, Z={self.Z})"
+        argument_dict = {'T_e': self.T_e,
+                         'n_e': self.n_e,
+                         'particle': self.particle,
+                         'Z': self.Z}
+
+        return call_string(PlasmaBlob, (), argument_dict)
 
     @property
     def electron_temperature(self):
diff --git a/plasmapy/utils/pytest_helpers.py b/plasmapy/utils/pytest_helpers.py
--- a/plasmapy/utils/pytest_helpers.py
+++ b/plasmapy/utils/pytest_helpers.py
@@ -87,8 +87,24 @@ def call_string(f: typing.Callable,
                 ) -> str:
     """Return a string with the equivalent call of a function."""
 
+    def format_quantity(arg):
+        formatted = f'{arg.value}'
+        for base, power in zip(arg.unit.bases, arg.unit.powers):
+            if power == -1:
+                formatted += f"/u.{base}"
+            elif power == 1:
+                formatted += f"*u.{base}"
+            else:
+                formatted += f"*u.{base}**{power}"
+        return formatted
+
     def format_arg(arg):
-        return arg.__name__ if hasattr(arg, '__name__') else repr(arg)
+        if hasattr(arg, '__name__'):
+            return arg.__name__
+        elif isinstance(arg, u.quantity.Quantity):
+            return format_quantity(arg)
+        else:
+            return repr(arg)
 
     def format_kw(keyword):
         if isinstance(keyword, str):


Test patch: