<p dir="auto">Out of range axes are forbidden and raise an AxisError in <a href="https://numpy.org/devdocs/reference/generated/numpy.expand_dims.html?highlight=expand_dims#numpy-expand-dims" rel="nofollow">numpy.expand_dims</a>, but it seems that the rule only works to single parameter of axis, but a tuple of axes.</p>
<h3 dir="auto">Reproducing code example:</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np
x = np.array([1, 2])  # x.ndim = 1
y = np.expand_dims(x, axis=2)  # axis = 2 &gt; x.ndim is not allowed, and will raise an AxisError
y = np.expand_dims(x, axis=(2, 0))  # axis = 2 &gt; x.ndim but is allowed"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>
<span class="pl-s1">x</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">1</span>, <span class="pl-c1">2</span>])  <span class="pl-c"># x.ndim = 1</span>
<span class="pl-s1">y</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">expand_dims</span>(<span class="pl-s1">x</span>, <span class="pl-s1">axis</span><span class="pl-c1">=</span><span class="pl-c1">2</span>)  <span class="pl-c"># axis = 2 &gt; x.ndim is not allowed, and will raise an AxisError</span>
<span class="pl-s1">y</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">expand_dims</span>(<span class="pl-s1">x</span>, <span class="pl-s1">axis</span><span class="pl-c1">=</span>(<span class="pl-c1">2</span>, <span class="pl-c1">0</span>))  <span class="pl-c"># axis = 2 &gt; x.ndim but is allowed</span></pre></div>


<h3 dir="auto">Error message:</h3>
<blockquote>
<p dir="auto"><strong>AxisError                                 Traceback (most recent call last)</strong><br>
 in <br>
1 import numpy as np<br>
2 x = np.array([1, 2])  # x.ndim = 1<br>
----&gt; 3 y = np.expand_dims(x, axis=2)  # axis = 2 &gt; x.ndim is not allowed, and will raise an AxisError<br>
4 y = np.expand_dims(x, axis=(2, 0))  # axis = 2 &gt; x.ndim but is allowed</p>
</blockquote>
<blockquote>
<p dir="auto">&lt;<strong>array_function</strong> internals&gt; in expand_dims(*args, **kwargs)</p>
</blockquote>
<blockquote>
<p dir="auto">C:\Softwares\anaconda3\lib\site-packages\numpy\lib\shape_base.py in expand_dims(a, axis)<br>
595<br>
596     out_ndim = len(axis) + a.ndim<br>
--&gt; 597     axis = normalize_axis_tuple(axis, out_ndim)<br>
598<br>
599     shape_it = iter(a.shape)</p>
</blockquote>
<blockquote>
<p dir="auto">C:\Softwares\anaconda3\lib\site-packages\numpy\core\numeric.py in normalize_axis_tuple(axis, ndim, argname, allow_duplicate)<br>
1325             pass<br>
1326     # Going via an iterator directly is slower than via list comprehension.<br>
-&gt; 1327     axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis])<br>
1328     if not allow_duplicate and len(set(axis)) != len(axis):<br>
1329         if argname:</p>
</blockquote>
<blockquote>
<p dir="auto">C:\Softwares\anaconda3\lib\site-packages\numpy\core\numeric.py in (.0)<br>
1325             pass<br>
1326     # Going via an iterator directly is slower than via list comprehension.<br>
-&gt; 1327     axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis])<br>
1328     if not allow_duplicate and len(set(axis)) != len(axis):<br>
1329         if argname:</p>
</blockquote>
<blockquote>
<p dir="auto"><strong>AxisError: axis 2 is out of bounds for array of dimension 2</strong></p>
</blockquote>

<h3 dir="auto">Numpy/Python version information:</h3>
<p dir="auto">Python: 3.7.7<br>
Numpy: 1.81.1</p>
<p dir="auto">There are duplicated entries, and also <code class="notranslate">e-&gt;e</code> comes after <code class="notranslate">f-&gt;f</code>, which probably means there'll always be a conversion to float32.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; np.sqrt.types
['f-&gt;f', 'd-&gt;d', 'e-&gt;e', 'f-&gt;f', 'd-&gt;d', 'g-&gt;g', 'F-&gt;F', 'D-&gt;D', 'G-&gt;G', 'O-&gt;O']"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; np.sqrt.types
['f-&gt;f', 'd-&gt;d', 'e-&gt;e', 'f-&gt;f', 'd-&gt;d', 'g-&gt;g', 'F-&gt;F', 'D-&gt;D', 'G-&gt;G', 'O-&gt;O']
</code></pre></div>