Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

numpy: Overloads between scalars and arrays can produce confusing results #1392

Open
EricCousineau-TRI opened this issue May 11, 2018 · 2 comments

Comments

@EricCousineau-TRI
Copy link
Collaborator

Relates numpy/numpy#10404 - can transplant the main info here if need be

Given how NumPy permits converting arrays of size 1 to scalars (regardless of dimension), this can create confusing interplay between overloads of an array and a scalar numeric value, especially if the array type is meant to be implicitly convertible from int or float.

Reproduction code:

sm.def("overload_scalar", [](py::array_t<float>) { return "Vector"; });
sm.def("overload_scalar", [](int) { return "Int"; });
def test_overload_scalar():
    assert m.overload_scalar(0) == "Int"
    assert m.overload_scalar([0]) == "Vector"
    assert m.overload_scalar(np.array([0.])) == "Int"  # What???

As a workaround, a user could define some wrapper type, like scalar_only<T>, and an accompanying type_converter<scalar_only<T>>, which explicitly rejects any containers that are iterable.

Regarding how to solve this, I unfortunately do not have any good ideas (though it would be nice if/when numpy/numpy#10615 lands).

EricCousineau-TRI added a commit to EricCousineau-TRI/pybind11 that referenced this issue May 11, 2018
EricCousineau-TRI added a commit to EricCousineau-TRI/pybind11 that referenced this issue May 11, 2018
@EricCousineau-TRI
Copy link
Collaborator Author

EricCousineau-TRI commented May 11, 2018

Added something like the above workaround to the current PR: 5e75f0b

EDIT: Note that this can also be workaround by having required kwargs (is this easily supported by pybind11?), or by writing the dispatch manually by writing your function on py::object and doing your own overload (losing out on the nice error messages, though).

@eacousineau
Copy link
Contributor

Ran into some form of this (I think) when looking at #1785 / #1776.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants