Skip to content

Commit

Permalink
docs: cleanup for Python 3
Browse files Browse the repository at this point in the history
  • Loading branch information
henryiii committed Feb 10, 2022
1 parent cf5a439 commit 04b60dd
Show file tree
Hide file tree
Showing 14 changed files with 39 additions and 102 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ Goodies
In addition to the core functionality, pybind11 provides some extra
goodies:

- Python 2.7, 3.5+, and PyPy/PyPy3 7.3 are supported with an
implementation-agnostic interface.
- Python 3.5+, and PyPy3 7.3 are supported with an
implementation-agnostic interface (pybind11 2.9 for Python 2).

This comment has been minimized.

Copy link
@rwgk

rwgk Feb 10, 2022

Collaborator

(pybind11 2.9 was the last version to support Python 2)

?
(I'd be puzzled by the current shorter version)


- It is possible to bind C++11 lambda functions with captured
variables. The lambda capture data is stored inside the resulting
Expand Down
19 changes: 3 additions & 16 deletions docs/advanced/cast/strings.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
Strings, bytes and Unicode conversions
######################################

.. note::

This section discusses string handling in terms of Python 3 strings. For
Python 2.7, replace all occurrences of ``str`` with ``unicode`` and
``bytes`` with ``str``. Python 2.7 users may find it best to use ``from
__future__ import unicode_literals`` to avoid unintentionally using ``str``
instead of ``unicode``.

Passing Python strings to C++
=============================

Expand Down Expand Up @@ -58,9 +50,9 @@ Passing bytes to C++
--------------------

A Python ``bytes`` object will be passed to C++ functions that accept
``std::string`` or ``char*`` *without* conversion. On Python 3, in order to
make a function *only* accept ``bytes`` (and not ``str``), declare it as taking
a ``py::bytes`` argument.
``std::string`` or ``char*`` *without* conversion. In order to make a function
*only* accept ``bytes`` (and not ``str``), declare it as taking a ``py::bytes``
argument.


Returning C++ strings to Python
Expand Down Expand Up @@ -204,11 +196,6 @@ decoded to Python ``str``.
}
);

.. warning::

Wide character strings may not work as described on Python 2.7 or Python
3.3 compiled with ``--enable-unicode=ucs2``.

Strings in multibyte encodings such as Shift-JIS must transcoded to a
UTF-8/16/32 before being returned to Python.

Expand Down
29 changes: 11 additions & 18 deletions docs/advanced/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -813,26 +813,21 @@ An instance can now be pickled as follows:

.. code-block:: python
try:
import cPickle as pickle # Use cPickle on Python 2.7
except ImportError:
import pickle
import pickle
p = Pickleable("test_value")
p.setExtra(15)
data = pickle.dumps(p, 2)
data = pickle.dumps(p)
.. note::
Note that only the cPickle module is supported on Python 2.7.

The second argument to ``dumps`` is also crucial: it selects the pickle
protocol version 2, since the older version 1 is not supported. Newer
versions are also fine—for instance, specify ``-1`` to always use the
latest available version. Beware: failure to follow these instructions
will cause important pybind11 memory allocation routines to be skipped
during unpickling, which will likely lead to memory corruption and/or
segmentation faults.
If given, the second argument to ``dumps`` must be 2 or larger - 0 and 1 are
not supported. Newer versions are also fine; for instance, specify ``-1`` to
always use the latest available version. Beware: failure to follow these
instructions will cause important pybind11 memory allocation routines to be
skipped during unpickling, which will likely lead to memory corruption
and/or segmentation faults. Python defaults to version 3 (Python 3-3.7) and
version 4 for Python 3.8+.

.. seealso::

Expand All @@ -849,11 +844,9 @@ Python normally uses references in assignments. Sometimes a real copy is needed
to prevent changing all copies. The ``copy`` module [#f5]_ provides these
capabilities.

On Python 3, a class with pickle support is automatically also (deep)copy
A class with pickle support is automatically also (deep)copy
compatible. However, performance can be improved by adding custom
``__copy__`` and ``__deepcopy__`` methods. With Python 2.7, these custom methods
are mandatory for (deep)copy compatibility, because pybind11 only supports
cPickle.
``__copy__`` and ``__deepcopy__`` methods.

For simple classes (deep)copy can be enabled by using the copy constructor,
which should look as follows:
Expand Down
6 changes: 3 additions & 3 deletions docs/advanced/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,8 @@ an invalid state.
Chaining exceptions ('raise from')
==================================

In Python 3.3 a mechanism for indicating that exceptions were caused by other
exceptions was introduced:
Python has a mechanism for indicating that exceptions were caused by other
exceptions:

.. code-block:: py
Expand All @@ -340,7 +340,7 @@ exceptions was introduced:
To do a similar thing in pybind11, you can use the ``py::raise_from`` function. It
sets the current python error indicator, so to continue propagating the exception
you should ``throw py::error_already_set()`` (Python 3 only).
you should ``throw py::error_already_set()``.

.. code-block:: cpp
Expand Down
8 changes: 0 additions & 8 deletions docs/advanced/pycpp/numpy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,6 @@ Ellipsis
Python 3 provides a convenient ``...`` ellipsis notation that is often used to
slice multidimensional arrays. For instance, the following snippet extracts the
middle dimensions of a tensor with the first and last index set to zero.
In Python 2, the syntactic sugar ``...`` is not available, but the singleton
``Ellipsis`` (of type ``ellipsis``) can still be used directly.

.. code-block:: python
Expand All @@ -414,8 +412,6 @@ operation on the C++ side:
py::array a = /* A NumPy array */;
py::array b = a[py::make_tuple(0, py::ellipsis(), 0)];
.. versionchanged:: 2.6
``py::ellipsis()`` is now also available in Python 2.
Memory view
===========
Expand Down Expand Up @@ -455,9 +451,5 @@ We can also use ``memoryview::from_memory`` for a simple 1D contiguous buffer:
);
})
.. note::

``memoryview::from_memory`` is not available in Python 2.

.. versionchanged:: 2.6
``memoryview::from_memory`` added.
6 changes: 3 additions & 3 deletions docs/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ load and execute the example:
.. code-block:: pycon
$ python
Python 2.7.10 (default, Aug 22 2015, 20:33:39)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.1)] on darwin
Python 3.9.10 (main, Jan 15 2022, 11:48:04)

This comment has been minimized.

Copy link
@rwgk

rwgk Feb 10, 2022

Collaborator

awesome :-)
thanks a lot for this level of attention to details!

[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.add(1, 2)
3L
3
>>>
.. _keyword_args:
Expand Down
11 changes: 1 addition & 10 deletions docs/compiling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -462,11 +462,8 @@ available in all modes. The targets provided are:
``pybind11::headers``
Just the pybind11 headers and minimum compile requirements

``pybind11::python2_no_register``
Quiets the warning/error when mixing C++14 or higher and Python 2

``pybind11::pybind11``
Python headers + ``pybind11::headers`` + ``pybind11::python2_no_register`` (Python 2 only)
Python headers + ``pybind11::headers``

``pybind11::python_link_helper``
Just the "linking" part of pybind11:module
Expand Down Expand Up @@ -583,12 +580,6 @@ using ``pip`` or ``conda``. If it hasn't, you can also manually specify
``-I <path-to-pybind11>/include`` together with the Python includes path
``python3-config --includes``.

Note that Python 2.7 modules don't use a special suffix, so you should simply
use ``example.so`` instead of ``example$(python3-config --extension-suffix)``.
Besides, the ``--extension-suffix`` option may or may not be available, depending
on the distribution; in the latter case, the module extension can be manually
set to ``.so``.

On macOS: the build command is almost the same but it also requires passing
the ``-undefined dynamic_lookup`` flag so as to ignore missing symbols when
building the module:
Expand Down
26 changes: 2 additions & 24 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ Frequently asked questions
filename of the extension library (without suffixes such as ``.so``).

2. If the above did not fix the issue, you are likely using an incompatible
version of Python (for instance, the extension library was compiled against
Python 2, while the interpreter is running on top of some version of Python
3, or vice versa).
version of Python that does not match what you compiled with.

"Symbol not found: ``__Py_ZeroStruct`` / ``_PyInstanceMethod_Type``"
========================================================================
Expand Down Expand Up @@ -289,27 +287,7 @@ Conflicts can arise, however, when using pybind11 in a project that *also* uses
the CMake Python detection in a system with several Python versions installed.

This difference may cause inconsistencies and errors if *both* mechanisms are
used in the same project. Consider the following CMake code executed in a
system with Python 2.7 and 3.x installed:

.. code-block:: cmake
find_package(PythonInterp)
find_package(PythonLibs)
find_package(pybind11)
It will detect Python 2.7 and pybind11 will pick it as well.

In contrast this code:

.. code-block:: cmake
find_package(pybind11)
find_package(PythonInterp)
find_package(PythonLibs)
will detect Python 3.x for pybind11 and may crash on
``find_package(PythonLibs)`` afterwards.
used in the same project.

There are three possible solutions:

Expand Down
10 changes: 5 additions & 5 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ class type_caster<bool> {
res = 0; // None is implicitly converted to False
}
#if defined(PYPY_VERSION)
// On PyPy, check that "__bool__" (or "__nonzero__" on Python 2.7) attr exists
// On PyPy, check that "__bool__" attr exists
else if (hasattr(src, PYBIND11_BOOL_ATTR)) {
res = PyObject_IsTrue(src.ptr());
}
Expand Down Expand Up @@ -383,8 +383,8 @@ struct string_caster {
return load_bytes(load_src);
}

// On Python 3.3, for UTF-8 we avoid the need for a temporary `bytes`
// object by using `PyUnicode_AsUTF8AndSize`.
// For UTF-8 we avoid the need for a temporary `bytes` object by using
// `PyUnicode_AsUTF8AndSize`.
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {
Py_ssize_t size = -1;
const auto *buffer
Expand Down Expand Up @@ -464,7 +464,7 @@ struct string_caster {
template <typename C = CharT>
bool load_bytes(enable_if_t<std::is_same<C, char>::value, handle> src) {
if (PYBIND11_BYTES_CHECK(src.ptr())) {
// We were passed a Python 3 raw bytes; accept it into a std::string or char*
// We were passed raw bytes; accept it into a std::string or char*
// without any encoding attempt.
const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr());
if (bytes) {
Expand Down Expand Up @@ -1279,7 +1279,7 @@ struct arg_v : arg {

/// \ingroup annotations
/// Annotation indicating that all following arguments are keyword-only; the is the equivalent of
/// an unnamed '*' argument (in Python 3)
/// an unnamed '*' argument
struct kw_only {};

/// \ingroup annotations
Expand Down
2 changes: 1 addition & 1 deletion include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
// If UNDEFINED, pybind11::str can only hold PyUnicodeObject, and
// pybind11::isinstance<str>() is true only for pybind11::str.
// However, for Python 2 only (!), the pybind11::str caster
// implicitly decodes bytes to PyUnicodeObject. This is to ease
// implicitly decoded bytes to PyUnicodeObject. This was to ease
// the transition from the legacy behavior to the non-permissive
// behavior.

Expand Down
8 changes: 4 additions & 4 deletions include/pybind11/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ PYBIND11_NAMESPACE_BEGIN(detail)

inline void ensure_builtins_in_globals(object &global) {
#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000
// Running exec and eval on Python 2 and 3 adds `builtins` module under
// `__builtins__` key to globals if not yet present.
// Python 3.8 made PyRun_String behave similarly. Let's also do that for
// older versions, for consistency. This was missing from PyPy3.8 7.3.7.
// Running exec and eval adds `builtins` module under `__builtins__` key to
// globals if not yet present. Python 3.8 made PyRun_String behave
// similarly. Let's also do that for older versions, for consistency. This
// was missing from PyPy3.8 7.3.7.
if (!global.contains("__builtins__"))
global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE);
#else
Expand Down
5 changes: 2 additions & 3 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,8 @@ class cpp_function : public function {
}
if (auto *tinfo = detail::get_type_info(*t)) {
handle th((PyObject *) tinfo->type);
signature += th.attr("__module__").cast<std::string>() + "." +
// Python 3.3+, but we backport it to earlier versions
th.attr("__qualname__").cast<std::string>();
signature += th.attr("__module__").cast<std::string>() + "."
+ th.attr("__qualname__").cast<std::string>();
} else if (rec->is_new_style_constructor && arg_index == 0) {
// A new-style `__init__` takes `self` as `value_and_holder`.
// Rewrite it to the proper class type.
Expand Down
2 changes: 0 additions & 2 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1903,8 +1903,6 @@ class memoryview : public object {
managed by Python. The caller is responsible for managing the lifetime
of ``mem``, which MUST outlive the memoryview constructed here.
This method is not available in Python 2.
See also: Python C API documentation for `PyMemoryView_FromBuffer`_.
.. _PyMemoryView_FromMemory:
Expand Down
5 changes: 2 additions & 3 deletions tests/test_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


def test_repr():
# In Python 3.3+, repr() accesses __qualname__
assert "pybind11_type" in repr(type(UserType))
assert "UserType" in repr(UserType)

Expand Down Expand Up @@ -102,8 +101,8 @@ def test_docstrings(doc):


def test_qualname(doc):
"""Tests that a properly qualified name is set in __qualname__ (even in pre-3.3, where we
backport the attribute) and that generated docstrings properly use it and the module name"""
"""Tests that a properly qualified name is set in __qualname__ and that
generated docstrings properly use it and the module name"""
assert m.NestBase.__qualname__ == "NestBase"
assert m.NestBase.Nested.__qualname__ == "NestBase.Nested"

Expand Down

0 comments on commit 04b60dd

Please sign in to comment.