-
Notifications
You must be signed in to change notification settings - Fork 2.2k
py::str x = py::none()
is a bit confusing; it converts None to a string, rather than setting the value to None
#2361
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
Comments
py::str x = py::none()
is a bit confusing; it converts None to a string, rather than setting the value to None
FWIW Trying to write a function like this yields a runtime m.def("test_str_with_default_arg_none" ,[](py::str value) {
return value;
}, py::arg("value") = py::none()); >>> m.test_str_with_default_arg_none()
E TypeError: test_str_with_default_arg_none(): incompatible function arguments. The following argument types are supported:
E 1. (value: str = None) -> str
E
E Invoked with: See add'l commit: |
@rwgk, more fun with strings? |
Yeah... I think it'd be hard to enforce anything explicit in C++ code, so I think a I'ma submit a quick draft PR anwyho. |
The Python 3 interpreter turns |
I'm just a bit concerned that we won't be able to express a difference between Will need to confirm this, though, with a quick example... |
This part, I wasn't sure of. I kind of thought of |
Oh, sorry, I think you're right (pretty sure now, I just looked around a bit to refresh my understanding). |
Yeah :( I think docs are the main route... FWIW Here're some
|
I just tried this:
This raises (I only tried Python 3):
|
Yeah, for certain types, it will fail fast (which is great); I have a test at least showing |
Actually, I can't reproduce, @EricCousineau-TRI #include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(example, m)
{
m.def("f" ,[](py::str value) {
return value;
});
} $ python3.8
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.f(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f(): incompatible function arguments. The following argument types are supported:
1. (arg0: str) -> str
Invoked with: None Am I missing something? Is this dependent on the right Python version? |
Alright, sorry. Misread and didn't open your commit. This is a pure C++ issue, then, where #define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun) \
PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \
/* This is deliberately not 'explicit' to allow implicit conversion from object: */ \
Name(const object &o) \
: Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) \
{ if (!m_ptr) throw error_already_set(); } \
Name(object &&o) \
: Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) \
{ if (!m_ptr) throw error_already_set(); } \
template <typename Policy_> \
Name(const ::pybind11::detail::accessor<Policy_> &a) : Name(object(a)) { } defines an implicit conversion (willingly and knowingly so, given the comment). |
Yeah... I've tried to encode that in the doc writeup + unittests in #2362 |
Uh oh!
There was an error while loading. Please reload this page.
Issue description
If I have a C++ function with
py::str
as an argument, I wanted to be able to default it topy::none()
. However, I was later surprised in my Python code because I was getting'None'
(a string version) rather than purelyNone
.Reproducible example code
See this patch here:
9c9b1f5
The test fails with the following:
I got bit in the following downstream code:
https://github.com/RobotLocomotion/drake/blob/feb254ea0a711c6596d7b8bf720672e0a5acd329/bindings/pydrake/common/deprecation_pybind.h#L21-L22
The workarounds I could think of:
py::object
, and then let Python code enforce the safe of string-ification.std::optional<std::string>
to make it more C++-ySuggestions
Two options:
py::str x = py::none()
(use None), assignmentpy::str x; x = py::none()
and make these set the object truly to None; for conversion,py::str(py::none())
, allow this to be stringified.py::none()
to objects in C++; This may happen with defautl arguments ...".The text was updated successfully, but these errors were encountered: