From 04b60dd41b1f0818f135bd6f6be5c5659e7ed32c Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 10 Feb 2022 16:47:34 -0500 Subject: [PATCH] docs: cleanup for Python 3 --- README.rst | 4 ++-- docs/advanced/cast/strings.rst | 19 +++---------------- docs/advanced/classes.rst | 29 +++++++++++------------------ docs/advanced/exceptions.rst | 6 +++--- docs/advanced/pycpp/numpy.rst | 8 -------- docs/basics.rst | 6 +++--- docs/compiling.rst | 11 +---------- docs/faq.rst | 26 ++------------------------ include/pybind11/cast.h | 10 +++++----- include/pybind11/detail/common.h | 2 +- include/pybind11/eval.h | 8 ++++---- include/pybind11/pybind11.h | 5 ++--- include/pybind11/pytypes.h | 2 -- tests/test_class.py | 5 ++--- 14 files changed, 39 insertions(+), 102 deletions(-) diff --git a/README.rst b/README.rst index e853e7bcde..5d1a6e2296 100644 --- a/README.rst +++ b/README.rst @@ -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). - It is possible to bind C++11 lambda functions with captured variables. The lambda capture data is stored inside the resulting diff --git a/docs/advanced/cast/strings.rst b/docs/advanced/cast/strings.rst index cfd7e7b7a5..e246c5219a 100644 --- a/docs/advanced/cast/strings.rst +++ b/docs/advanced/cast/strings.rst @@ -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++ ============================= @@ -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 @@ -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. diff --git a/docs/advanced/classes.rst b/docs/advanced/classes.rst index aea75e9813..3e8ba73852 100644 --- a/docs/advanced/classes.rst +++ b/docs/advanced/classes.rst @@ -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:: @@ -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: diff --git a/docs/advanced/exceptions.rst b/docs/advanced/exceptions.rst index 7cd8447b93..2211caf5d3 100644 --- a/docs/advanced/exceptions.rst +++ b/docs/advanced/exceptions.rst @@ -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 @@ -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 diff --git a/docs/advanced/pycpp/numpy.rst b/docs/advanced/pycpp/numpy.rst index 30daeefff9..dbc48440a6 100644 --- a/docs/advanced/pycpp/numpy.rst +++ b/docs/advanced/pycpp/numpy.rst @@ -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 @@ -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 =========== @@ -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. diff --git a/docs/basics.rst b/docs/basics.rst index e0479b298d..d40992d386 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -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) + [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: diff --git a/docs/compiling.rst b/docs/compiling.rst index 703a1d1949..f7303fd23f 100644 --- a/docs/compiling.rst +++ b/docs/compiling.rst @@ -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 @@ -583,12 +580,6 @@ using ``pip`` or ``conda``. If it hasn't, you can also manually specify ``-I /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: diff --git a/docs/faq.rst b/docs/faq.rst index e2f477b1f5..69c3442e3b 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -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``" ======================================================================== @@ -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: diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 9eebe56995..b12559ac8b 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -325,7 +325,7 @@ class type_caster { 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()); } @@ -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 @@ -464,7 +464,7 @@ struct string_caster { template bool load_bytes(enable_if_t::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) { @@ -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 diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 88248eb408..a5d98d71f8 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -269,7 +269,7 @@ // If UNDEFINED, pybind11::str can only hold PyUnicodeObject, and // pybind11::isinstance() 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. diff --git a/include/pybind11/eval.h b/include/pybind11/eval.h index aa46ed67db..c157a00957 100644 --- a/include/pybind11/eval.h +++ b/include/pybind11/eval.h @@ -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 diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 565db21481..7b7a1a05dd 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -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() + "." + - // Python 3.3+, but we backport it to earlier versions - th.attr("__qualname__").cast(); + signature += th.attr("__module__").cast() + "." + + th.attr("__qualname__").cast(); } 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. diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 268490bf86..29f70bd5fd 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -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: diff --git a/tests/test_class.py b/tests/test_class.py index 2fe5c63111..ff9196f0f2 100644 --- a/tests/test_class.py +++ b/tests/test_class.py @@ -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) @@ -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"