{"record":{"id":"e27e1da199e02f17","repo":"TheAlgorithms/Python","slug":"angle-must-be-an-angle-object","errorCode":null,"errorMessage":"angle must be an Angle object.","messagePattern":"angle must be an Angle object\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"geometry/geometry.py","lineNumber":73,"sourceCode":"    >>> Side(5, None)\n    Traceback (most recent call last):\n        ...\n    TypeError: angle must be an Angle object.\n    >>> Side(5, Angle(90), \"Invalid next_side\")\n    Traceback (most recent call last):\n        ...\n    TypeError: next_side must be a Side or None.\n    \"\"\"\n\n    length: float\n    angle: Angle = field(default_factory=Angle)\n    next_side: Side | None = None\n\n    def __post_init__(self) -> None:\n        if not isinstance(self.length, (int, float)) or self.length <= 0:\n            raise TypeError(\"length must be a positive numeric value.\")\n        if not isinstance(self.angle, Angle):\n            raise TypeError(\"angle must be an Angle object.\")\n        if not isinstance(self.next_side, (Side, NoneType)):\n            raise TypeError(\"next_side must be a Side or None.\")\n\n\n@dataclass\nclass Ellipse:\n    \"\"\"\n    A geometric Ellipse on a 2D surface\n\n    >>> Ellipse(5, 10)\n    Ellipse(major_radius=5, minor_radius=10)\n    >>> Ellipse(5, 10) is Ellipse(5, 10)\n    False\n    >>> Ellipse(5, 10) == Ellipse(5, 10)\n    True\n    \"\"\"\n\n    major_radius: float","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/geometry/geometry.py#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Construct the angle explicitly: Side(5, angle=Angle(90)) — check Angle's docstring for its constructor units (degrees vs radians)","If the value comes from external data, convert it first: Side(5, angle=Angle(float(raw_value)))","If building a chain of sides, ensure each next_side is a Side built the same way"],"exampleFix":"# before\nside = Side(5, angle=90)\n\n# after\nfrom geometry.geometry import Side, Angle\nside = Side(5, angle=Angle(90))","handlingStrategy":"type-guard","validationCode":"from geometry.geometry import Side, Angle\n\nif not isinstance(angle_value, Angle):\n    angle_value = Angle(angle_value)  # or raise your own error\nside = Side(length, angle=angle_value)","typeGuard":"def is_angle(value: object) -> bool:\n    from geometry.geometry import Angle\n    return isinstance(value, Angle)","tryCatchPattern":null,"preventionTips":["Always construct Angle explicitly instead of relying on raw numbers","Wrap external data loading in a to_side() helper that builds Side/Angle for you"],"tags":["geometry","type-validation","dataclass"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}