Repository: scipy/scipy

Issue:
DOC: show how to use solve_ivp with one arg
<!-- 
Thanks for contributing a pull request! Please ensure that
your PR satisfies the checklist before submitting:
http://scipy.github.io/devdocs/dev/contributor/development_workflow.html#checklist-before-submitting-a-pr

Also, please name and describe your PR as you would write a
commit message:
https://docs.scipy.org/doc/numpy/dev/development_workflow.html#writing-the-commit-message

Note that we are a team of volunteers; we appreciate your
patience during the review process.

Again, thanks for contributing!
-->

#### Reference issue
<!--Example: Closes gh-WXYZ.-->
Closes issue in stackoverflow https://stackoverflow.com/questions/53262552/cant-integrate-with-dblquad

#### What does this implement/fix?
Tell user, that if they have only one argument, they cannot simply use tuple. Because in python (a) != (a,)

#### Additional information
<!--Any additional information you think is important.-->


Discussion:
Hi, thanks for contributing!

Sorry but this is out of scope as more of a Python syntax thing. The documentation is already stating that it needs a tuple so this does not add anything. At most we could add a validation of the parameter itself to check that it can be unpacked. But as is I would close this.

If you would like to propose a validation check instead, let me know. Otherwise, I will close.
@tupui, I understand your comment--this adds a hint about an elementary Python behavior.  However, I've seen enough people stumble over this in stackoverflow questions that my immediate response to the added line was "Yes, that will be helpful."   However (that's a level 2 "however"), if we include it here because it will help avoid a common mistake, we should include it in the docstrings of all the functions that accept an `args` argument like this.   I wouldn't be against that, but I'm not sure what other devs would think.
ISTM, (1) this is a good change, this syntax often trips python beginners; (2) we can treat these comments piecemeal and add these comments when looking at code for some other reason. 
I would prefer to have a better error message, so have this on the validation of the arguments side (as we now tend to validate all arguments). But if this is really a pain point, why not. We should decide on a concise message and IMO do it at one for all occurrences.

Resolving patch:
diff --git a/scipy/integrate/_ivp/ivp.py b/scipy/integrate/_ivp/ivp.py
--- a/scipy/integrate/_ivp/ivp.py
+++ b/scipy/integrate/_ivp/ivp.py
@@ -515,6 +515,15 @@ def solve_ivp(fun, t_span, y0, method='RK45', t_eval=None, dense_output=False,
         # Wrap the user's fun (and jac, if given) in lambdas to hide the
         # additional parameters.  Pass in the original fun as a keyword
         # argument to keep it in the scope of the lambda.
+        try:
+            _ = [*(args)]
+        except TypeError as exp:
+            suggestion_tuple = (
+                "Supplied 'args' cannot be unpacked. Please supply `args`"
+                f" as a tuple (e.g. `args=({args},)`)"
+            )
+            raise TypeError(suggestion_tuple) from exp
+
         fun = lambda t, x, fun=fun: fun(t, x, *args)
         jac = options.get('jac')
         if callable(jac):


Test patch:
diff --git a/scipy/integrate/_ivp/tests/test_ivp.py b/scipy/integrate/_ivp/tests/test_ivp.py
--- a/scipy/integrate/_ivp/tests/test_ivp.py
+++ b/scipy/integrate/_ivp/tests/test_ivp.py
@@ -1008,3 +1008,15 @@ def test_integration_zero_rhs(method):
     assert_(result.success)
     assert_equal(result.status, 0)
     assert_allclose(result.y, 1.0, rtol=1e-15)
+
+
+def test_args_single_value():
+    def fun_with_arg(t, y, a):
+        return a*y
+
+    message = "Supplied 'args' cannot be unpacked."
+    with pytest.raises(TypeError, match=message):
+        solve_ivp(fun_with_arg, (0, 0.1), [1], args=-1)
+
+    sol = solve_ivp(fun_with_arg, (0, 0.1), [1], args=(-1,))
+    assert_allclose(sol.y[0, -1], np.exp(-0.1))