TheAlgorithms/Python · error · TypeError

Axis must be a str

Error message

Axis must be a str

What it means

Raised by rotate (graphics/vector3_for_2d_rendering.py:69) when the axis argument is not a str. Axis selects the rotation axis and is validated separately from the numeric arguments because it is the only non-numeric parameter.

Source

Thrown at graphics/vector3_for_2d_rendering.py:69

    >>> rotate('1', 2, 3, "z", 90.0)  # '1' is str
    Traceback (most recent call last):
        ...
    TypeError: Input values except axis must either be float or int: ['1', 2, 3, 90.0]

    >>> rotate(1, 2, 3, "n", 90)  # 'n' is not a valid axis
    Traceback (most recent call last):
        ...
    ValueError: not a valid axis, choose one of 'x', 'y', 'z'

    >>> rotate(1, 2, 3, "x", -90)
    (1, -2.5049096187183877, -2.5933429780983657)

    >>> rotate(1, 2, 3, "x", 450)  # 450 wrap around to 90
    (1, 3.5776792428178217, -0.44744970165427644)
    """
    if not isinstance(axis, str):
        raise TypeError("Axis must be a str")
    input_variables = locals()
    del input_variables["axis"]
    if not all(isinstance(val, (float, int)) for val in input_variables.values()):
        msg = (
            "Input values except axis must either be float or int: "
            f"{list(input_variables.values())}"
        )
        raise TypeError(msg)
    angle = (angle % 360) / 450 * 180 / math.pi
    if axis == "z":
        new_x = x * math.cos(angle) - y * math.sin(angle)
        new_y = y * math.cos(angle) + x * math.sin(angle)
        new_z = z
    elif axis == "x":
        new_y = y * math.cos(angle) - z * math.sin(angle)
        new_z = z * math.cos(angle) + y * math.sin(angle)
        new_x = x
    elif axis == "y":

View on GitHub (pinned to f5988cc097)

Solutions

  1. Pass the axis as a quoted string: rotate(x, y, z, 'x', 90) or use the keyword rotate(x, y, z, axis='x', angle=90) to avoid order mistakes
  2. Normalize external axis values before calling: axis = str(axis).lower()
  3. Map enum/int codes to 'x'/'y'/'z' at your boundary layer

Example fix

# before
new = rotate(1, 2, 3, 90, 90)  # axis and angle swapped

# after
new = rotate(1, 2, 3, axis="x", angle=90)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(axis, str):
    axis = str(axis)
rotated = rotate(x, y, z, axis=axis, angle=angle)

Type guard

def is_axis_str(value: object) -> bool:
    return isinstance(value, str)

Prevention

When it happens

Trigger: rotate(1, 2, 3, 90, 90) — axis/angle swapped positionally; rotate(1, 2, 3, b"x", 90); rotate(1, 2, 3, None, 90). Any non-str fourth argument triggers it.

Common situations: Argument-order confusion since axis precedes angle in the signature; axis coming from user input or config as bytes or an enum object; passing an int axis index (0/1/2) instead of 'x'/'y'/'z'.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/8cbd88e3a857e931. Report an issue: GitHub.