TheAlgorithms/Python · error · ValueError

surface_area_torus() does not support spindle or self inters

Error message

surface_area_torus() does not support spindle or self intersecting tori

What it means

surface_area_torus() raises this ValueError when torus_radius < tube_radius, i.e. the tube is thicker than the ring it wraps. Such a torus is a spindle or self-intersecting torus, for which the simple formula 4 * pi^2 * R * r is not the (outer) surface area, so the library refuses to compute a wrong answer. Note: torus_radius == tube_radius (horn torus) is allowed.

Source

Thrown at maths/area.py:233

        ...
    ValueError: surface_area_torus() does not support spindle or self intersecting tori
    >>> surface_area_torus(1.6, 1.6)
    101.06474906715503
    >>> surface_area_torus(0, 0)
    0.0
    >>> surface_area_torus(-1, 1)
    Traceback (most recent call last):
        ...
    ValueError: surface_area_torus() only accepts non-negative values
    >>> surface_area_torus(1, -1)
    Traceback (most recent call last):
        ...
    ValueError: surface_area_torus() only accepts non-negative values
    """
    if torus_radius < 0 or tube_radius < 0:
        raise ValueError("surface_area_torus() only accepts non-negative values")
    if torus_radius < tube_radius:
        raise ValueError(
            "surface_area_torus() does not support spindle or self intersecting tori"
        )
    return 4 * pow(pi, 2) * torus_radius * tube_radius


def area_rectangle(length: float, width: float) -> float:
    """
    Calculate the area of a rectangle.

    >>> area_rectangle(10, 20)
    200
    >>> area_rectangle(1.6, 2.6)
    4.16
    >>> area_rectangle(0, 0)
    0
    >>> area_rectangle(-1, -2)
    Traceback (most recent call last):
        ...

View on GitHub (pinned to f5988cc097)

Solutions

  1. Check torus_radius >= tube_radius before calling; if the arguments were swapped, swap them back.
  2. Constrain parameter sweeps/UI sliders so tube_radius can never exceed torus_radius.
  3. If you genuinely need a spindle/self-intersecting torus area, use a geometry kernel (e.g. trimesh/CGAL) instead of this function.
  4. Catch ValueError and report both radii in the message.

Example fix

// before
area = surface_area_torus(tube, ring)  # arguments swapped

# after
area = surface_area_torus(ring, tube)  # ring >= tube

# or guard explicitly:
if tube > ring:
    raise ValueError('tube radius must not exceed torus radius')
Defensive patterns

Strategy: validation

Validate before calling

if torus_radius < tube_radius:
    raise ValueError(
        f'spindle torus not supported: torus_radius={torus_radius} < tube_radius={tube_radius}'
    )
area = surface_area_torus(torus_radius, tube_radius)

Type guard

def is_ring_torus(R: float, r: float) -> bool:
    return R >= r

Try / catch

try:
    area = surface_area_torus(R, r)
except ValueError as e:
    if 'spindle' in str(e):
        raise ValueError(f'geometry not supported, swap or resize radii: R={R}, r={r}') from e
    raise

Prevention

When it happens

Trigger: Calling surface_area_torus(R, r) with R < r, e.g. surface_area_torus(2, 3). Often caused by swapping the two positional arguments, since both are just radii.

Common situations: Argument-order confusion because both parameters are radii with no type distinction; parametric sweeps that let the tube grow past the ring radius; UI sliders without a constraint linking the two values.

Related errors


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