Repository: sympy/sympy

Issue:
Regression in Quaternion.subs()
```pycon
>>> from sympy.algebras import Quaternion
>>> from sympy.abc import alpha
>>> q = Quaternion.from_axis_angle((0, 0, 1), alpha)
>>> q.subs(alpha, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[...]/sympy/core/basic.py", line 1123, in subs
    rv = rv._subs(old, new, **kwargs)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/sympy/core/cache.py", line 72, in wrapper
    retval = cfunc(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/sympy/core/basic.py", line 1235, in _subs
    rv = self._eval_subs(old, new)
         ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/sympy/algebras/quaternion.py", line 1004, in _eval_subs
    norm = norm.subs(*args)
           ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'subs'
```

This happens in the `master` branch since #25753.

Discussion:

Patch:
diff --git a/sympy/algebras/quaternion.py b/sympy/algebras/quaternion.py
index e5a8ee2d90..ee03b7503f 100644
--- a/sympy/algebras/quaternion.py
+++ b/sympy/algebras/quaternion.py
@@ -1001,7 +1001,8 @@ def _ln(self):
     def _eval_subs(self, *args):
         elements = [i.subs(*args) for i in self.args]
         norm = self._norm
-        norm = norm.subs(*args)
+        if norm is not None:
+            norm = norm.subs(*args)
         _check_norm(elements, norm)
         return Quaternion(*elements, norm=norm)
 


Test patch:
diff --git a/sympy/algebras/tests/test_quaternion.py b/sympy/algebras/tests/test_quaternion.py
index f052304247..8215635c83 100644
--- a/sympy/algebras/tests/test_quaternion.py
+++ b/sympy/algebras/tests/test_quaternion.py
@@ -1,3 +1,4 @@
+from sympy.testing.pytest import slow
 from sympy.core.function import diff
 from sympy.core.function import expand
 from sympy.core.numbers import (E, I, Rational, pi)
@@ -134,6 +135,11 @@ def test_quaternion_complex_real_addition():
     assert q1 - q1 == q0
 
 
+def test_quaternion_subs():
+    q = Quaternion.from_axis_angle((0, 0, 1), phi)
+    assert q.subs(phi, 0) == Quaternion(1, 0, 0, 0)
+
+
 def test_quaternion_evalf():
     assert (Quaternion(sqrt(2), 0, 0, sqrt(3)).evalf() ==
             Quaternion(sqrt(2).evalf(), 0, 0, sqrt(3).evalf()))
@@ -355,6 +361,7 @@ def test_issue_16318():
     assert (axis, angle) == q.to_axis_angle()
 
 
+@slow
 def test_to_euler():
     q = Quaternion(w, x, y, z)
     q_normalized = q.normalize()
@@ -396,6 +403,7 @@ def test_one_case(angles, seq):
     test_one_case((pi/2,  -pi/2, 0), 'ZYX')
 
 
+@slow
 def test_to_euler_options():
     def test_one_case(q):
         angles1 = Matrix(q.to_euler(seq, True, True))