diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2df314606..17e67ded4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -67,14 +67,32 @@ repos: hooks: - id: pycln +- repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.9.0 + hooks: + - id: python-check-blanket-noqa + - id: python-check-blanket-type-ignore + - id: python-no-log-warn + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal + # Flake8 also supports pre-commit natively (same author) - repo: https://github.com/PyCQA/flake8 rev: 3.9.2 hooks: - id: flake8 - additional_dependencies: [flake8-bugbear, pep8-naming] + additional_dependencies: &flake8_dependencies + - flake8-bugbear + - pep8-naming exclude: ^(docs/.*|tools/.*)$ +- repo: https://github.com/asottile/yesqa + rev: v1.2.3 + hooks: + - id: yesqa + additional_dependencies: *flake8_dependencies + # CMake formatting - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 @@ -86,12 +104,9 @@ repos: # Check static types with mypy - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.910 + rev: v0.910-1 hooks: - id: mypy - # The default Python type ignores .pyi files, so let's rerun if detected - types: [text] - files: ^pybind11.*\.pyi?$ # Running per-file misbehaves a bit, so just run on all files, it's fast pass_filenames: false additional_dependencies: [typed_ast] diff --git a/docs/advanced/classes.rst b/docs/advanced/classes.rst index 5f01a2f11..6330af5eb 100644 --- a/docs/advanced/classes.rst +++ b/docs/advanced/classes.rst @@ -1266,7 +1266,7 @@ Custom type setup ================= For advanced use cases, such as enabling garbage collection support, you may -wish to directly manipulate the `PyHeapTypeObject` corresponding to a +wish to directly manipulate the ``PyHeapTypeObject`` corresponding to a ``py::class_`` definition. You can do that using ``py::custom_type_setup``: diff --git a/docs/advanced/embedding.rst b/docs/advanced/embedding.rst index a435b8a75..dd980d483 100644 --- a/docs/advanced/embedding.rst +++ b/docs/advanced/embedding.rst @@ -40,15 +40,15 @@ The essential structure of the ``main.cpp`` file looks like this: } The interpreter must be initialized before using any Python API, which includes -all the functions and classes in pybind11. The RAII guard class `scoped_interpreter` +all the functions and classes in pybind11. The RAII guard class ``scoped_interpreter`` takes care of the interpreter lifetime. After the guard is destroyed, the interpreter shuts down and clears its memory. No Python functions can be called after this. Executing Python code ===================== -There are a few different ways to run Python code. One option is to use `eval`, -`exec` or `eval_file`, as explained in :ref:`eval`. Here is a quick example in +There are a few different ways to run Python code. One option is to use ``eval``, +``exec`` or ``eval_file``, as explained in :ref:`eval`. Here is a quick example in the context of an executable with an embedded interpreter: .. code-block:: cpp @@ -108,7 +108,7 @@ The two approaches can also be combined: Importing modules ================= -Python modules can be imported using `module_::import()`: +Python modules can be imported using ``module_::import()``: .. code-block:: cpp @@ -134,7 +134,7 @@ embedding the interpreter. This makes it easy to import local Python files: int n = result.cast(); assert(n == 3); -Modules can be reloaded using `module_::reload()` if the source is modified e.g. +Modules can be reloaded using ``module_::reload()`` if the source is modified e.g. by an external process. This can be useful in scenarios where the application imports a user defined data processing script which needs to be updated after changes by the user. Note that this function does not reload modules recursively. @@ -144,7 +144,7 @@ changes by the user. Note that this function does not reload modules recursively Adding embedded modules ======================= -Embedded binary modules can be added using the `PYBIND11_EMBEDDED_MODULE` macro. +Embedded binary modules can be added using the ``PYBIND11_EMBEDDED_MODULE`` macro. Note that the definition must be placed at global scope. They can be imported like any other module. @@ -170,7 +170,7 @@ like any other module. Unlike extension modules where only a single binary module can be created, on the embedded side an unlimited number of modules can be added using multiple -`PYBIND11_EMBEDDED_MODULE` definitions (as long as they have unique names). +``PYBIND11_EMBEDDED_MODULE`` definitions (as long as they have unique names). These modules are added to Python's list of builtins, so they can also be imported in pure Python files loaded by the interpreter. Everything interacts @@ -216,9 +216,9 @@ naturally: Interpreter lifetime ==================== -The Python interpreter shuts down when `scoped_interpreter` is destroyed. After +The Python interpreter shuts down when ``scoped_interpreter`` is destroyed. After this, creating a new instance will restart the interpreter. Alternatively, the -`initialize_interpreter` / `finalize_interpreter` pair of functions can be used +``initialize_interpreter`` / ``finalize_interpreter`` pair of functions can be used to directly set the state at any time. Modules created with pybind11 can be safely re-initialized after the interpreter @@ -230,8 +230,8 @@ global data. All the details can be found in the CPython documentation. .. warning:: - Creating two concurrent `scoped_interpreter` guards is a fatal error. So is - calling `initialize_interpreter` for a second time after the interpreter + Creating two concurrent ``scoped_interpreter`` guards is a fatal error. So is + calling ``initialize_interpreter`` for a second time after the interpreter has already been initialized. Do not use the raw CPython API functions ``Py_Initialize`` and @@ -242,7 +242,7 @@ global data. All the details can be found in the CPython documentation. Sub-interpreter support ======================= -Creating multiple copies of `scoped_interpreter` is not possible because it +Creating multiple copies of ``scoped_interpreter`` is not possible because it represents the main Python interpreter. Sub-interpreters are something different and they do permit the existence of multiple interpreters. This is an advanced feature of the CPython API and should be handled with care. pybind11 does not @@ -258,5 +258,5 @@ We'll just mention a couple of caveats the sub-interpreters support in pybind11: 2. Managing multiple threads, multiple interpreters and the GIL can be challenging and there are several caveats here, even within the pure CPython API (please refer to the Python docs for details). As for - pybind11, keep in mind that `gil_scoped_release` and `gil_scoped_acquire` + pybind11, keep in mind that ``gil_scoped_release`` and ``gil_scoped_acquire`` do not take sub-interpreters into account. diff --git a/docs/advanced/exceptions.rst b/docs/advanced/exceptions.rst index 2aaa0ad32..b4825cbcd 100644 --- a/docs/advanced/exceptions.rst +++ b/docs/advanced/exceptions.rst @@ -96,18 +96,18 @@ A matching function is available for registering a local exception translator: It is possible to specify base class for the exception using the third -parameter, a `handle`: +parameter, a ``handle``: .. code-block:: cpp py::register_exception(module, "PyExp", PyExc_RuntimeError); py::register_local_exception(module, "PyExp", PyExc_RuntimeError); -Then `PyExp` can be caught both as `PyExp` and `RuntimeError`. +Then ``PyExp`` can be caught both as ``PyExp`` and ``RuntimeError``. The class objects of the built-in Python exceptions are listed in the Python documentation on `Standard Exceptions `_. -The default base class is `PyExc_Exception`. +The default base class is ``PyExc_Exception``. When more advanced exception translation is needed, the functions ``py::register_exception_translator(translator)`` and diff --git a/docs/advanced/functions.rst b/docs/advanced/functions.rst index 1178d0726..abd1084ab 100644 --- a/docs/advanced/functions.rst +++ b/docs/advanced/functions.rst @@ -232,7 +232,7 @@ is equivalent to the following pseudocode: }); The only requirement is that ``T`` is default-constructible, but otherwise any -scope guard will work. This is very useful in combination with `gil_scoped_release`. +scope guard will work. This is very useful in combination with ``gil_scoped_release``. See :ref:`gil`. Multiple guards can also be specified as ``py::call_guard``. The diff --git a/docs/advanced/misc.rst b/docs/advanced/misc.rst index b3f3b2265..edab15fcb 100644 --- a/docs/advanced/misc.rst +++ b/docs/advanced/misc.rst @@ -84,7 +84,7 @@ could be realized as follows (important changes highlighted): }); } -The ``call_go`` wrapper can also be simplified using the `call_guard` policy +The ``call_go`` wrapper can also be simplified using the ``call_guard`` policy (see :ref:`call_policies`) which yields the same result: .. code-block:: cpp diff --git a/docs/advanced/pycpp/utilities.rst b/docs/advanced/pycpp/utilities.rst index bf90a62f8..af0f9cb2b 100644 --- a/docs/advanced/pycpp/utilities.rst +++ b/docs/advanced/pycpp/utilities.rst @@ -28,7 +28,7 @@ Capturing standard output from ostream Often, a library will use the streams ``std::cout`` and ``std::cerr`` to print, but this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr`` -redirection. Replacing a library's printing with `py::print ` may not +redirection. Replacing a library's printing with ``py::print `` may not be feasible. This can be fixed using a guard around the library function that redirects output to the corresponding Python streams: @@ -62,9 +62,9 @@ This method respects flushes on the output streams and will flush if needed when the scoped guard is destroyed. This allows the output to be redirected in real time, such as to a Jupyter notebook. The two arguments, the C++ stream and the Python output, are optional, and default to standard output if not given. An -extra type, `py::scoped_estream_redirect `, is identical +extra type, ``py::scoped_estream_redirect ``, is identical except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with -`py::call_guard`, which allows multiple items, but uses the default constructor: +``py::call_guard``, which allows multiple items, but uses the default constructor: .. code-block:: cpp @@ -74,7 +74,7 @@ except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful wi py::scoped_estream_redirect>()); The redirection can also be done in Python with the addition of a context -manager, using the `py::add_ostream_redirect() ` function: +manager, using the ``py::add_ostream_redirect() `` function: .. code-block:: cpp @@ -103,7 +103,7 @@ arguments to disable one of the streams if needed. Evaluating Python expressions from strings and files ==================================================== -pybind11 provides the `eval`, `exec` and `eval_file` functions to evaluate +pybind11 provides the ``eval``, ``exec`` and ``eval_file`` functions to evaluate Python expressions and statements. The following example illustrates how they can be used. diff --git a/docs/changelog.rst b/docs/changelog.rst index 80c580b18..0721020db 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -251,8 +251,8 @@ New features: Changes: -* ``py::str`` changed to exclusively hold `PyUnicodeObject`. Previously - ``py::str`` could also hold `bytes`, which is probably surprising, was +* ``py::str`` changed to exclusively hold ``PyUnicodeObject``. Previously + ``py::str`` could also hold ``bytes``, which is probably surprising, was never documented, and can mask bugs (e.g. accidental use of ``py::str`` instead of ``py::bytes``). `#2409 `_ @@ -1405,7 +1405,7 @@ v2.2.0 (August 31, 2017) * Intel C++ compiler compatibility fixes. `#937 `_. -* Fixed implicit conversion of `py::enum_` to integer types on Python 2.7. +* Fixed implicit conversion of ``py::enum_`` to integer types on Python 2.7. `#821 `_. * Added ``py::hash`` to fetch the hash value of Python objects, and diff --git a/tests/test_buffers.py b/tests/test_buffers.py index e3df7e04f..adf7cadff 100644 --- a/tests/test_buffers.py +++ b/tests/test_buffers.py @@ -5,7 +5,7 @@ import struct import pytest -import env # noqa: F401 +import env from pybind11_tests import ConstructorStats from pybind11_tests import buffers as m diff --git a/tests/test_builtin_casters.py b/tests/test_builtin_casters.py index 09b4b08c5..2a061c193 100644 --- a/tests/test_builtin_casters.py +++ b/tests/test_builtin_casters.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import pytest -import env # noqa: F401 +import env from pybind11_tests import IncType, UserType from pybind11_tests import builtin_casters as m diff --git a/tests/test_callbacks.py b/tests/test_callbacks.py index edbb1890c..f41ad86e7 100644 --- a/tests/test_callbacks.py +++ b/tests/test_callbacks.py @@ -4,7 +4,7 @@ from threading import Thread import pytest -import env # NOQA: F401 +import env # noqa: F401 from pybind11_tests import callbacks as m diff --git a/tests/test_enum.py b/tests/test_enum.py index 85302b080..14c754e72 100644 --- a/tests/test_enum.py +++ b/tests/test_enum.py @@ -96,13 +96,13 @@ Members: y >= object() # noqa: B015 with pytest.raises(TypeError): - y | object() # noqa: B015 + y | object() with pytest.raises(TypeError): - y & object() # noqa: B015 + y & object() with pytest.raises(TypeError): - y ^ object() # noqa: B015 + y ^ object() assert int(m.UnscopedEnum.ETwo) == 2 assert str(m.UnscopedEnum(2)) == "UnscopedEnum.ETwo" diff --git a/tests/test_methods_and_attributes.py b/tests/test_methods_and_attributes.py index 21909654a..866b3cea1 100644 --- a/tests/test_methods_and_attributes.py +++ b/tests/test_methods_and_attributes.py @@ -102,7 +102,7 @@ def test_properties(): assert instance.def_property == 3 with pytest.raises(AttributeError) as excinfo: - dummy = instance.def_property_writeonly # noqa: F841 unused var + dummy = instance.def_property_writeonly # unused var assert "unreadable attribute" in str(excinfo.value) instance.def_property_writeonly = 4 @@ -127,7 +127,7 @@ def test_static_properties(): assert m.TestProperties.def_readwrite_static == 2 with pytest.raises(AttributeError) as excinfo: - dummy = m.TestProperties.def_writeonly_static # noqa: F841 unused var + dummy = m.TestProperties.def_writeonly_static # unused var assert "unreadable attribute" in str(excinfo.value) m.TestProperties.def_writeonly_static = 3 diff --git a/tests/test_pickling.py b/tests/test_pickling.py index e39463d20..9f68f37dc 100644 --- a/tests/test_pickling.py +++ b/tests/test_pickling.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import pytest -import env # noqa: F401 +import env from pybind11_tests import pickling as m try: diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index cc27e60a1..5215b79bc 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -5,7 +5,7 @@ import sys import pytest -import env # noqa: F401 +import env from pybind11_tests import debug_enabled from pybind11_tests import pytypes as m @@ -610,7 +610,7 @@ def test_weakref(create_weakref, create_weakref_with_callback): obj = WeaklyReferenced() assert getweakrefcount(obj) == 0 - wr = create_weakref(obj) # noqa: F841 + wr = create_weakref(obj) assert getweakrefcount(obj) == 1 obj = WeaklyReferenced() diff --git a/tests/test_stl_binders.py b/tests/test_stl_binders.py index a68dcd31d..59c5ab6b5 100644 --- a/tests/test_stl_binders.py +++ b/tests/test_stl_binders.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import pytest -import env # noqa: F401 +import env from pybind11_tests import stl_binders as m