numpy/numpy · error · NotImplementedError

Unknown ctypes type {t.__name__}

Error message

Unknown ctypes type {t.__name__}

What it means

`dtype_from_ctypes_type` handles Arrays, Pointers, Structures, Unions, and scalar types with a `_type_` string. Any ctypes type that is none of these (e.g. a ctypes function pointer `CFUNCTYPE`, a `_CData` subclass, or a custom ctypes object without `_type_`) falls through to NotImplementedError with the type's name.

Source

Thrown at numpy/_core/_dtype_ctypes.py:119


def dtype_from_ctypes_type(t):
    """
    Construct a dtype object from a ctypes type
    """
    import _ctypes
    if issubclass(t, _ctypes.Array):
        return _from_ctypes_array(t)
    elif issubclass(t, _ctypes._Pointer):
        raise TypeError("ctypes pointers have no dtype equivalent")
    elif issubclass(t, _ctypes.Structure):
        return _from_ctypes_structure(t)
    elif issubclass(t, _ctypes.Union):
        return _from_ctypes_union(t)
    elif isinstance(getattr(t, '_type_', None), str):
        return _from_ctypes_scalar(t)
    else:
        raise NotImplementedError(
            f"Unknown ctypes type {t.__name__}")

View on GitHub (pinned to e117b3ca4e)

Solutions

  1. Map the unsupported ctypes type to an explicit numpy dtype yourself (e.g. function pointer -> np.dtype('P') / np.uintp).
  2. Avoid passing function-pointer/callback ctypes types through np.dtype; handle them separately in your FFI layer.
  3. Pre-check the ctypes type kind before calling np.dtype and branch to the right conversion.

Example fix

// before
fptype = ctypes.CFUNCTYPE(None, ctypes.c_int)
np.dtype(fptype)   # NotImplementedError: Unknown ctypes type

// after
np.dtype(np.uintp)   # represent pointer-sized handle explicitly
Defensive patterns

Strategy: type-guard

Validate before calling

import _ctypes
def is_supported_ctypes(t) -> bool:
    return (issubclass(t, _ctypes.Array) or issubclass(t, _ctypes.Structure)
            or issubclass(t, _ctypes.Union)
            or isinstance(getattr(t,'_type_',None), str))
if not is_supported_ctypes(MyType):
    raise NotImplementedError(f'no numpy dtype for {MyType.__name__}')

Type guard

import _ctypes
def is_convertible_ctypes(t) -> bool:
    return issubclass(t, (_ctypes.Array, _ctypes.Structure, _ctypes.Union)) or isinstance(getattr(t,'_type_',None), str)

Try / catch

try:
    dt = np.dtype(t)
except NotImplementedError:
    dt = np.dtype(np.uintp)   # generic pointer-sized fallback

Prevention

When it happens

Trigger: Calling np.dtype on a ctypes function pointer type (`CFUNCTYPE(...)`), a `ctypes.c_void_p` in some edge cases, or a non-standard ctypes subclass without `_type_`. Also wrapping ctypes callback types.

Common situations: FFI code that passes arbitrary ctypes objects to numpy; auto-conversion layers that try `np.dtype(x)` on every ctypes type.

Related errors


AI-assisted analysis of numpy/numpy@e117b3ca4e (2026-08-07). Data as JSON: /api/errors/2760d05053a55ecb. Report an issue: GitHub.