Repository: sympy/sympy

Issue:
Creating a vector raises a deprecation warning and need better error message
Looks like a deprecation warning for sympify is now appearing with sympy mechanics objects. Also, we need a better error message if you accidentally swap the order of arguments in `orient_axis()` (or its companion methods).

```
In [2]: import sympy.physics.mechanics as me

In [3]: theta = me.dynamicsymbols('theta')

In [4]: N = ReferenceFrame('N')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-4-563293f48d8e> in <module>
----> 1 N = ReferenceFrame('N')

NameError: name 'ReferenceFrame' is not defined

In [5]: N = me.ReferenceFrame('N')

In [6]: A = me.ReferenceFrame('A')

In [7]: A.orient_axis(N, theta, N.x + N.y + N.z)
/home/moorepants/miniconda/lib/python3.7/site-packages/sympy/core/sympify.py:462: SymPyDeprecationWarning: 

String fallback in sympify has been deprecated since SymPy 1.6. Use
sympify(str(obj)) or sympy.core.sympify.converter or obj._sympy_
instead. See https://github.com/sympy/sympy/issues/18066 for more
info.

  deprecated_since_version='1.6'
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
ValueError: Error from parse_expr with transformed code: 'N .x +N .y +N .z '

The above exception was the direct cause of the following exception:

AttributeError                            Traceback (most recent call last)
<ipython-input-7-28003ca07dd8> in <module>
----> 1 A.orient_axis(N, theta, N.x + N.y + N.z)

~/miniconda/lib/python3.7/site-packages/sympy/physics/vector/frame.py in orient_axis(self, parent, axis, angle)
    611         _check_frame(parent)
    612 
--> 613         amount = sympify(angle)
    614         theta = amount
    615         axis = _check_vector(axis)

~/miniconda/lib/python3.7/site-packages/sympy/core/sympify.py in sympify(a, locals, convert_xor, strict, rational, evaluate)
    477     try:
    478         a = a.replace('\n', '')
--> 479         expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
    480     except (TokenError, SyntaxError) as exc:
    481         raise SympifyError('could not parse %r' % a, exc)

~/miniconda/lib/python3.7/site-packages/sympy/parsing/sympy_parser.py in parse_expr(s, local_dict, transformations, global_dict, evaluate)
   1016         return eval_expr(code, local_dict, global_dict)
   1017     except Exception as e:
-> 1018         raise e from ValueError(f"Error from parse_expr with transformed code: {code!r}")
   1019 
   1020 

~/miniconda/lib/python3.7/site-packages/sympy/parsing/sympy_parser.py in parse_expr(s, local_dict, transformations, global_dict, evaluate)
   1014 
   1015     try:
-> 1016         return eval_expr(code, local_dict, global_dict)
   1017     except Exception as e:
   1018         raise e from ValueError(f"Error from parse_expr with transformed code: {code!r}")

~/miniconda/lib/python3.7/site-packages/sympy/parsing/sympy_parser.py in eval_expr(code, local_dict, global_dict)
    909     """
    910     expr = eval(
--> 911         code, global_dict, local_dict)  # take local objects in preference
    912     return expr
    913 

<string> in <module>

AttributeError: 'function' object has no attribute 'x'
```

Discussion:

Patch:
diff --git a/sympy/physics/vector/frame.py b/sympy/physics/vector/frame.py
index e181a7d367..3d54fd402f 100644
--- a/sympy/physics/vector/frame.py
+++ b/sympy/physics/vector/frame.py
@@ -646,9 +646,12 @@ def orient_axis(self, parent, axis, angle):
         from sympy.physics.vector.functions import dynamicsymbols
         _check_frame(parent)
 
+        if not isinstance(axis, Vector) and isinstance(angle, Vector):
+            axis, angle = angle, axis
+
+        axis = _check_vector(axis)
         amount = sympify(angle)
         theta = amount
-        axis = _check_vector(axis)
         parent_orient_axis = []
 
         if not axis.dt(parent) == 0:


Test patch:
diff --git a/sympy/physics/vector/tests/test_frame.py b/sympy/physics/vector/tests/test_frame.py
index 819ba0cb54..5a040ce875 100644
--- a/sympy/physics/vector/tests/test_frame.py
+++ b/sympy/physics/vector/tests/test_frame.py
@@ -453,7 +453,15 @@ def test_orient_explicit():
 def test_orient_axis():
     A = ReferenceFrame('A')
     B = ReferenceFrame('B')
-    assert A.orient_axis(B,-B.x, 1) == A.orient_axis(B, B.x, -1)
+    A.orient_axis(B,-B.x, 1)
+    A1 = A.dcm(B)
+    A.orient_axis(B, B.x, -1)
+    A2 = A.dcm(B)
+    A.orient_axis(B, 1, -B.x)
+    A3 = A.dcm(B)
+    assert A1 == A2
+    assert A2 == A3
+    raises(TypeError, lambda: A.orient_axis(B, 1, 1))
 
 def test_orient_body():
     A = ReferenceFrame('A')