-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Changing pybind11::str to exclusively hold PyUnicodeObject #2409
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,31 @@ modernization and other useful information. | |
|
||
.. _upgrade-guide-2.6: | ||
|
||
v2.7 | ||
==== | ||
|
||
*Before* v2.7, ``py::str`` can hold ``PyUnicodeObject`` or ``PyBytesObject``, | ||
and ``py::isinstance<str>()`` is ``true`` for both ``py::str`` and | ||
``py::bytes``. Starting with v2.7, ``py::str`` exclusively holds | ||
``PyUnicodeObject`` (`#2409 <https://github.com/pybind/pybind11/pull/2409>`_), | ||
and ``py::isinstance<str>()`` is ``true`` only for ``py::str``. To help in | ||
the transition of user code, the ``PYBIND11_STR_LEGACY_PERMISSIVE`` macro | ||
is provided as an escape hatch to go back to the legacy behavior. This macro | ||
will be removed in future releases. Two types of required fixes are expected | ||
to be common: | ||
|
||
* Accidental use of ``py::str`` instead of ``py::bytes``, masked by the legacy | ||
behavior. These are probably very easy to fix, by changing from | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might mention this is probably a bug? |
||
``py::str`` to ``py::bytes``. | ||
|
||
* Reliance on py::isinstance<str>(obj) being ``true`` for | ||
``py::bytes``. This is likely to be easy to fix in most cases by adding | ||
``|| py::isinstance<bytes>(obj)``, but a fix may be more involved, e.g. if | ||
``py::isinstance<T>`` appears in a template. Such situations will require | ||
careful review and custom fixes. | ||
|
||
|
||
|
||
v2.6 | ||
==== | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1656,6 +1656,17 @@ struct pyobject_caster { | |
|
||
template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0> | ||
bool load(handle src, bool /* convert */) { | ||
#if PY_MAJOR_VERSION < 3 && !defined(PYBIND11_STR_LEGACY_PERMISSIVE) | ||
// For Python 2, without this implicit conversion, Python code would | ||
// need to be cluttered with six.ensure_text() or similar, only to be | ||
// un-cluttered later after Python 2 support is dropped. | ||
if (std::is_same<T, str>::value && isinstance<bytes>(src)) { | ||
PyObject *str_from_bytes = PyUnicode_FromEncodedObject(src.ptr(), "utf-8", nullptr); | ||
if (!str_from_bytes) throw error_already_set(); | ||
value = reinterpret_steal<type>(str_from_bytes); | ||
return true; | ||
} | ||
#endif | ||
Comment on lines
+1659
to
+1669
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alternatively, if we don't want this here (cfr. @wjakob's remark), we could specialize |
||
if (!isinstance<type>(src)) | ||
return false; | ||
value = reinterpret_borrow<type>(src); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,7 +144,7 @@ template <typename Type, typename Value> struct list_caster { | |
using value_conv = make_caster<Value>; | ||
|
||
bool load(handle src, bool convert) { | ||
if (!isinstance<sequence>(src) || isinstance<str>(src)) | ||
if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we actually don't want this change. Doing so (or well, not doing so) would fix #1807. I'm OK with making and discussing this change (or undoing your change) in a separate PR, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See also #2198. |
||
return false; | ||
auto s = reinterpret_borrow<sequence>(src); | ||
value.clear(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: how do we want to approach this, w.r.t. merging the current version into
master
? How confusing will it be ifmaster
already contains parts of an v2.7 upgrade guide?Not really related to this PR though; @rwgk is just a bit unlucky that this might be the first PR for v2.7 with bigger changes that require notes in the upgrade guide.