PyO3/pyo3 · error

Empty enum

Error message

Empty enum

What it means

When generating `FromPyObject` implementations for an enum, pyo3 unions the input type expressions of all variants to know which Python types the enum can extract from. `reduce` on an empty iterator returns None, so an enum with zero variants panics with 'Empty enum'. Rust also disallows empty enums at the type level, so this usually indicates macro-generated or partially-written code.

Source

Thrown at pyo3-macros-backend/src/frompyobject.rs:108

            ::core::result::Result::Err(
                #pyo3_path::impl_::frompyobject::failed_to_extract_enum(
                    obj.py(),
                    #ty_name,
                    &[#(#variant_names),*],
                    &[#(#error_names),*],
                    &errors
                )
            )
        )
    }

    #[cfg(feature = "experimental-inspect")]
    fn input_type(&self) -> PyExpr {
        self.variants
            .iter()
            .map(|var| var.input_type())
            .reduce(PyExpr::union)
            .expect("Empty enum")
    }
}

struct NamedStructField<'a> {
    ident: &'a syn::Ident,
    getter: Option<FieldGetter>,
    from_py_with: Option<FromPyWithAttribute>,
    default: Option<DefaultAttribute>,
    ty: &'a syn::Type,
}

struct TupleStructField {
    from_py_with: Option<FromPyWithAttribute>,
    ty: syn::Type,
}

/// Container Style
///

View on GitHub (pinned to ac9b6899d3)

Solutions

  1. Add at least one variant to the enum
  2. Remove the derive/impl for the empty enum and handle it explicitly (e.g. an uninhabited type converter)
  3. Fix the code generator to skip empty enums

Example fix

// before
#[derive(FromPyObject)]
enum Shape {}
// after
#[derive(FromPyObject)]
enum Shape {
    Circle { r: f64 },
    Square { s: f64 },
}
Defensive patterns

Strategy: validation

Validate before calling

// fail fast when generating derives for empty enums
if variants.is_empty() { return Err("cannot derive FromPyObject on empty enum".into()); }

Prevention

When it happens

Trigger: Deriving FromPyObject on a Rust enum declared with no variants, e.g. `enum Never {}` inside the pyo3 derive path.

Common situations: Placeholder empty enums left during refactors; code generators emitting enums with zero variants for empty unions/oneOf schemas.

Related errors


AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05). Data as JSON: /api/errors/add48c1e0d601a24. Report an issue: GitHub.