TheAlgorithms/Python · error · TypeError

angle must be an Angle object.

Error message

angle must be an Angle object.

What it means

Raised by Side.__post_init__ (geometry/geometry.py:73) when the angle field is not an instance of the Angle class. Side is a dataclass whose API requires angles to be expressed as Angle objects (which have their own units/validation), not raw numbers or strings. The check runs on every construction, including defaults.

Source

Thrown at geometry/geometry.py:73

    >>> Side(5, None)
    Traceback (most recent call last):
        ...
    TypeError: angle must be an Angle object.
    >>> Side(5, Angle(90), "Invalid next_side")
    Traceback (most recent call last):
        ...
    TypeError: next_side must be a Side or None.
    """

    length: float
    angle: Angle = field(default_factory=Angle)
    next_side: Side | None = None

    def __post_init__(self) -> None:
        if not isinstance(self.length, (int, float)) or self.length <= 0:
            raise TypeError("length must be a positive numeric value.")
        if not isinstance(self.angle, Angle):
            raise TypeError("angle must be an Angle object.")
        if not isinstance(self.next_side, (Side, NoneType)):
            raise TypeError("next_side must be a Side or None.")


@dataclass
class Ellipse:
    """
    A geometric Ellipse on a 2D surface

    >>> Ellipse(5, 10)
    Ellipse(major_radius=5, minor_radius=10)
    >>> Ellipse(5, 10) is Ellipse(5, 10)
    False
    >>> Ellipse(5, 10) == Ellipse(5, 10)
    True
    """

    major_radius: float

View on GitHub (pinned to f5988cc097)

Solutions

  1. Construct the angle explicitly: Side(5, angle=Angle(90)) — check Angle's docstring for its constructor units (degrees vs radians)
  2. If the value comes from external data, convert it first: Side(5, angle=Angle(float(raw_value)))
  3. If building a chain of sides, ensure each next_side is a Side built the same way

Example fix

# before
side = Side(5, angle=90)

# after
from geometry.geometry import Side, Angle
side = Side(5, angle=Angle(90))
Defensive patterns

Strategy: type-guard

Validate before calling

from geometry.geometry import Side, Angle

if not isinstance(angle_value, Angle):
    angle_value = Angle(angle_value)  # or raise your own error
side = Side(length, angle=angle_value)

Type guard

def is_angle(value: object) -> bool:
    from geometry.geometry import Angle
    return isinstance(value, Angle)

Prevention

When it happens

Trigger: Calling Side(5, angle=45), Side(5, angle=math.radians(90)), or Side(5, angle='90') — any angle argument that is a plain int/float/str instead of Angle. Also constructing a Polygon and passing non-Angle values via add_side.

Common situations: Developers migrating from an API that took degrees as a float; building sides from parsed CSV/JSON data where angles arrive as strings; forgetting that Angle is a class with its own constructor.

Related errors


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