Skip to content

[BUG]: Argument conversion in dispatcher assumes sequence protocol when casting to list[<something>]  #5558

@IljaManakov

Description

@IljaManakov

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

2.13.6

Problem description

When a derived class implements __getitem__ and there exists an overloaded function that can accept a vector of base instances or the derived instance the argument conversion in the dispatcher logic will try to call derived.__getitem__.
If derived does not implement __len__ this will fail outright, otherwise derived.__getitem__ will be called with integer indices from 0 to len(derived). If derived.__getitem__ does not accept integers (e.g. because it mimics a map) this will also fail.

The resulting error message is extremely confusing because the trace will show that the execution failed at the function call but the message will say that __getitem__ was involved with derived and 0 but supported types are ...

A potential fix / workaround is to manually break the sequence protocol for derived by setting its tp_as_sequence->sq_item to NULL as this will cause it to fail PySequence_Check and avoid this conversion path entirely.

Adding noconvert to the vector argument does not help because this failure already happens in the initial non-converting pass in the dispatcher.

Reproducible example code

I have created a minimal example here: https://github.com/IljaManakov/pybind_arg_cast_issue_repro

Is this a regression? Put the last known working version here if it is.

Not a regression

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageNew bug, unverified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions