Repository: PlasmaPy/PlasmaPy
Pull request #493 (2018-06-10 08:30:08)

Use @particle_input decorator on functions in collisions.py
Addresses #336.

I've used `@particle_input` decorator wherever possible on functions in `collisions.py`. Also, replaced `TypeError` with a `ValueError` in `particle_input` when number of input elements do not match expected elements in the tuple passed, since it seems more fitting. :)


Patch:
diff --git a/plasmapy/atomic/particle_input.py b/plasmapy/atomic/particle_input.py
index 0a687011..17aa11b1 100644
--- a/plasmapy/atomic/particle_input.py
+++ b/plasmapy/atomic/particle_input.py
@@ -131,6 +131,10 @@ def particle_input(wrapped_function: Callable = None,
         or `~plasmapy.atomic.Particle`; or if `Z` or `mass_numb` is
         not an `int`.
 
+    `ValueError`
+        If the number of input elements in a collection do not match the
+        number of expected elements.
+
     `~plasmapy/utils/InvalidParticleError`
         If the annotated argument does not correspond to a valid
         particle.
@@ -242,7 +246,7 @@ def wrapper(*args, **kwargs):
                     expected_params = len(annotated_argnames)
                     received_params = len(arguments[argname])
                     if not expected_params == received_params:
-                        raise TypeError(
+                        raise ValueError(
                             f"Number of parameters allowed in the tuple "
                             f"({expected_params} parameters) are "
                             f"not equal to number of parameters passed in "
diff --git a/plasmapy/physics/transport/collisions.py b/plasmapy/physics/transport/collisions.py
index 577c15b9..55191061 100644
--- a/plasmapy/physics/transport/collisions.py
+++ b/plasmapy/physics/transport/collisions.py
@@ -75,9 +75,10 @@
 
 @utils.check_quantity(T={"units": u.K, "can_be_negative": False},
                       n_e={"units": u.m ** -3})
+@atomic.particle_input
 def Coulomb_logarithm(T,
                       n_e,
-                      particles,
+                      particles: (atomic.Particle, atomic.Particle),
                       z_mean=np.nan * u.dimensionless_unscaled,
                       V=np.nan * u.m / u.s,
                       method="classical"):
@@ -287,7 +288,8 @@ def Coulomb_logarithm(T,
     return ln_Lambda
 
 
-def _boilerPlate(T, particles, V):
+@atomic.particle_input
+def _boilerPlate(T, particles: (atomic.Particle, atomic.Particle), V):
     """
     Some boiler plate code for checking if inputs to functions in
     collisions.py are good. Also obtains reduced in mass in a
@@ -295,13 +297,7 @@ def _boilerPlate(T, particles, V):
     """
     # checking temperature is in correct units
     T = T.to(u.K, equivalencies=u.temperature_energy())
-    # extracting particle information
-    if not isinstance(particles, (list, tuple)) or len(particles) != 2:
-        raise ValueError("Particles input must be a "
-                         "list or tuple containing representations of two  "
-                         f"charged particles. Got {particles} instead.")
 
-    particles = [atomic.Particle(p) for p in particles]
     masses = [p.mass for p in particles]
     charges = [np.abs(p.charge) for p in particles]
 
@@ -341,8 +337,9 @@ def _replaceNanVwithThermalV(V, T, m):
 
 
 @check_quantity(T={"units": u.K, "can_be_negative": False})
+@atomic.particle_input
 def impact_parameter_perp(T,
-                          particles,
+                          particles: (atomic.Particle, atomic.Particle),
                           V=np.nan * u.m / u.s):
     r"""Distance of closest approach for a 90 degree Coulomb collision.
 


Test patch:
diff --git a/plasmapy/atomic/tests/test_particle_input.py b/plasmapy/atomic/tests/test_particle_input.py
index a5a7017f..17377f9a 100644
--- a/plasmapy/atomic/tests/test_particle_input.py
+++ b/plasmapy/atomic/tests/test_particle_input.py
@@ -270,7 +270,7 @@ def test_list_annotation(particles: Union[Tuple, List]):
 
 
 def test_invalid_number_of_tuple_elements():
-    with pytest.raises(TypeError):
+    with pytest.raises(ValueError):
         # Passed 3 elements when function only takes 2 in tuple
         function_with_tuple_annotation(('e+', 'e-', 'alpha'), q='test')