diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b9e37e5fe..4245641ba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,8 +19,10 @@ repos: hooks: - id: check-added-large-files - id: check-case-conflict + - id: check-docstring-first - id: check-merge-conflict - id: check-symlinks + - id: check-toml - id: check-yaml - id: debug-statements - id: end-of-file-fixer @@ -42,12 +44,16 @@ repos: # Black, the code formatter, natively supports pre-commit - repo: https://github.com/psf/black - rev: 21.9b0 + rev: 21.9b0 # Keep in sync with blacken-docs hooks: - id: black - # By default, this ignores pyi files, though black supports them - types: [text] - files: \.pyi?$ + +- repo: https://github.com/asottile/blacken-docs + rev: v1.11.0 + hooks: + - id: blacken-docs + additional_dependencies: + - black==21.9b0 # keep in sync with black hook # Changes tabs to spaces - repo: https://github.com/Lucas-C/pre-commit-hooks @@ -55,6 +61,12 @@ repos: hooks: - id: remove-tabs +# Autoremoves unused imports +- repo: https://github.com/hadialqattan/pycln + rev: v1.0.3 + hooks: + - id: pycln + # Flake8 also supports pre-commit natively (same author) - repo: https://github.com/PyCQA/flake8 rev: 3.9.2 @@ -86,7 +98,7 @@ repos: # Checks the manifest for missing files (native support) - repo: https://github.com/mgedmin/check-manifest - rev: "0.46" + rev: "0.47" hooks: - id: check-manifest # This is a slow hook, so only run this if --hook-stage manual is passed @@ -100,10 +112,10 @@ repos: exclude: ".supp$" args: ["-L", "nd,ot,thist"] -- repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.7.2.1 - hooks: - - id: shellcheck +- repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.7.2.1 + hooks: + - id: shellcheck # The original pybind11 checks for a few C++ style items - repo: local diff --git a/docs/advanced/cast/custom.rst b/docs/advanced/cast/custom.rst index a779444c2..19b935347 100644 --- a/docs/advanced/cast/custom.rst +++ b/docs/advanced/cast/custom.rst @@ -26,7 +26,9 @@ The following Python snippet demonstrates the intended usage from the Python sid def __int__(self): return 123 + from example import print + print(A()) To register the necessary conversion routines, it is necessary to add an diff --git a/docs/advanced/cast/eigen.rst b/docs/advanced/cast/eigen.rst index e01472d5a..80f101343 100644 --- a/docs/advanced/cast/eigen.rst +++ b/docs/advanced/cast/eigen.rst @@ -112,7 +112,7 @@ example: .. code-block:: python a = MyClass() - m = a.get_matrix() # flags.writeable = True, flags.owndata = False + m = a.get_matrix() # flags.writeable = True, flags.owndata = False v = a.view_matrix() # flags.writeable = False, flags.owndata = False c = a.copy_matrix() # flags.writeable = True, flags.owndata = True # m[5,6] and v[5,6] refer to the same element, c[5,6] does not. @@ -203,7 +203,7 @@ adding the ``order='F'`` option when creating an array: .. code-block:: python - myarray = np.array(source, order='F') + myarray = np.array(source, order="F") Such an object will be passable to a bound function accepting an ``Eigen::Ref`` (or similar column-major Eigen type). diff --git a/docs/advanced/cast/strings.rst b/docs/advanced/cast/strings.rst index e25701eca..cfd7e7b7a 100644 --- a/docs/advanced/cast/strings.rst +++ b/docs/advanced/cast/strings.rst @@ -36,13 +36,13 @@ everywhere `_. } ); -.. code-block:: python +.. code-block:: pycon - >>> utf8_test('🎂') + >>> utf8_test("🎂") utf-8 is icing on the cake. 🎂 - >>> utf8_charptr('🍕') + >>> utf8_charptr("🍕") My favorite food is 🍕 @@ -80,7 +80,7 @@ raise a ``UnicodeDecodeError``. } ); -.. code-block:: python +.. code-block:: pycon >>> isinstance(example.std_string_return(), str) True @@ -114,7 +114,7 @@ conversion has the same overhead as implicit conversion. } ); -.. code-block:: python +.. code-block:: pycon >>> str_output() 'Send your résumé to Alice in HR' @@ -143,7 +143,7 @@ returned to Python as ``bytes``, then one can return the data as a } ); -.. code-block:: python +.. code-block:: pycon >>> example.return_bytes() b'\xba\xd0\xba\xd0' @@ -160,7 +160,7 @@ encoding, but cannot convert ``std::string`` back to ``bytes`` implicitly. } ); -.. code-block:: python +.. code-block:: pycon >>> isinstance(example.asymmetry(b"have some bytes"), str) True @@ -229,16 +229,16 @@ character. m.def("pass_char", [](char c) { return c; }); m.def("pass_wchar", [](wchar_t w) { return w; }); -.. code-block:: python +.. code-block:: pycon - >>> example.pass_char('A') + >>> example.pass_char("A") 'A' While C++ will cast integers to character types (``char c = 0x65;``), pybind11 does not convert Python integers to characters implicitly. The Python function ``chr()`` can be used to convert integers to characters. -.. code-block:: python +.. code-block:: pycon >>> example.pass_char(0x65) TypeError @@ -259,17 +259,17 @@ a combining acute accent). The combining character will be lost if the two-character sequence is passed as an argument, even though it renders as a single grapheme. -.. code-block:: python +.. code-block:: pycon - >>> example.pass_wchar('é') + >>> example.pass_wchar("é") 'é' - >>> combining_e_acute = 'e' + '\u0301' + >>> combining_e_acute = "e" + "\u0301" >>> combining_e_acute 'é' - >>> combining_e_acute == 'é' + >>> combining_e_acute == "é" False >>> example.pass_wchar(combining_e_acute) @@ -278,9 +278,9 @@ single grapheme. Normalizing combining characters before passing the character literal to C++ may resolve *some* of these issues: -.. code-block:: python +.. code-block:: pycon - >>> example.pass_wchar(unicodedata.normalize('NFC', combining_e_acute)) + >>> example.pass_wchar(unicodedata.normalize("NFC", combining_e_acute)) 'é' In some languages (Thai for example), there are `graphemes that cannot be diff --git a/docs/advanced/classes.rst b/docs/advanced/classes.rst index 9d1b1f0d9..7f8fcdf4b 100644 --- a/docs/advanced/classes.rst +++ b/docs/advanced/classes.rst @@ -136,7 +136,7 @@ a virtual method call. u'woof! woof! woof! ' >>> class Cat(Animal): ... def go(self, n_times): - ... return "meow! " * n_times + ... return "meow! " * n_times ... >>> c = Cat() >>> call_go(c) @@ -159,8 +159,9 @@ Here is an example: class Dachshund(Dog): def __init__(self, name): - Dog.__init__(self) # Without this, a TypeError is raised. + Dog.__init__(self) # Without this, a TypeError is raised. self.name = name + def bark(self): return "yap!" @@ -1153,6 +1154,7 @@ error: >>> class PyFinalChild(IsFinal): ... pass + ... TypeError: type 'IsFinal' is not an acceptable base type .. note:: This attribute is currently ignored on PyPy @@ -1247,7 +1249,7 @@ Accessing the type object You can get the type object from a C++ class that has already been registered using: -.. code-block:: python +.. code-block:: cpp py::type T_py = py::type::of(); diff --git a/docs/advanced/embedding.rst b/docs/advanced/embedding.rst index dfdaad2d7..a435b8a75 100644 --- a/docs/advanced/embedding.rst +++ b/docs/advanced/embedding.rst @@ -122,6 +122,7 @@ embedding the interpreter. This makes it easy to import local Python files: """calc.py located in the working directory""" + def add(i, j): return i + j diff --git a/docs/advanced/functions.rst b/docs/advanced/functions.rst index a537cb65e..1178d0726 100644 --- a/docs/advanced/functions.rst +++ b/docs/advanced/functions.rst @@ -272,7 +272,7 @@ And used in Python as usual: .. code-block:: pycon - >>> print_dict({'foo': 123, 'bar': 'hello'}) + >>> print_dict({"foo": 123, "bar": "hello"}) key=foo, value=123 key=bar, value=hello @@ -377,10 +377,11 @@ argument in a function definition: def f(a, *, b): # a can be positional or via keyword; b must be via keyword pass + f(a=1, b=2) # good f(b=2, a=1) # good - f(1, b=2) # good - f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given + f(1, b=2) # good + f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given Pybind11 provides a ``py::kw_only`` object that allows you to implement the same behaviour by specifying the object between positional and keyword-only diff --git a/docs/advanced/pycpp/numpy.rst b/docs/advanced/pycpp/numpy.rst index cae068e91..30daeefff 100644 --- a/docs/advanced/pycpp/numpy.rst +++ b/docs/advanced/pycpp/numpy.rst @@ -258,8 +258,8 @@ by the compiler. The result is returned as a NumPy array of type .. code-block:: pycon - >>> x = np.array([[1, 3],[5, 7]]) - >>> y = np.array([[2, 4],[6, 8]]) + >>> x = np.array([[1, 3], [5, 7]]) + >>> y = np.array([[2, 4], [6, 8]]) >>> z = 3 >>> result = vectorized_func(x, y, z) @@ -403,7 +403,7 @@ In Python 2, the syntactic sugar ``...`` is not available, but the singleton .. code-block:: python - a = # a NumPy array + a = ... # a NumPy array b = a[0, ..., 0] The function ``py::ellipsis()`` function can be used to perform the same diff --git a/docs/advanced/pycpp/object.rst b/docs/advanced/pycpp/object.rst index 6fa8d0708..8bffb83e1 100644 --- a/docs/advanced/pycpp/object.rst +++ b/docs/advanced/pycpp/object.rst @@ -173,6 +173,7 @@ Keyword arguments are also supported. In Python, there is the usual call syntax: def f(number, say, to): ... # function code + f(1234, say="hello", to=some_instance) # keyword call in Python In C++, the same call can be made using: diff --git a/docs/advanced/pycpp/utilities.rst b/docs/advanced/pycpp/utilities.rst index 30429e84d..bf90a62f8 100644 --- a/docs/advanced/pycpp/utilities.rst +++ b/docs/advanced/pycpp/utilities.rst @@ -66,7 +66,7 @@ extra type, `py::scoped_estream_redirect `, is identica 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: -.. code-block:: py +.. code-block:: cpp // Alternative: Call single function using call guard m.def("noisy_func", &call_noisy_function, diff --git a/docs/advanced/smart_ptrs.rst b/docs/advanced/smart_ptrs.rst index da57748ca..5a2220109 100644 --- a/docs/advanced/smart_ptrs.rst +++ b/docs/advanced/smart_ptrs.rst @@ -77,6 +77,7 @@ segmentation fault). .. code-block:: python from example import Parent + print(Parent().get_child()) The problem is that ``Parent::get_child()`` returns a pointer to an instance of diff --git a/docs/benchmark.py b/docs/benchmark.py index 369470c81..f19079367 100644 --- a/docs/benchmark.py +++ b/docs/benchmark.py @@ -2,7 +2,6 @@ import datetime as dt import os import random -import time nfns = 4 # Functions per class nargs = 4 # Arguments per function diff --git a/docs/changelog.rst b/docs/changelog.rst index 8b9690caa..6bdf6a6e4 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1142,6 +1142,7 @@ v2.2.0 (August 31, 2017) from cpp_module import CppBase1, CppBase2 + class PyDerived(CppBase1, CppBase2): def __init__(self): CppBase1.__init__(self) # C++ bases must be initialized explicitly diff --git a/docs/classes.rst b/docs/classes.rst index f3610ef36..a4463e417 100644 --- a/docs/classes.rst +++ b/docs/classes.rst @@ -44,12 +44,12 @@ interactive Python session demonstrating this example is shown below: % python >>> import example - >>> p = example.Pet('Molly') + >>> p = example.Pet("Molly") >>> print(p) >>> p.getName() u'Molly' - >>> p.setName('Charly') + >>> p.setName("Charly") >>> p.getName() u'Charly' @@ -122,10 +122,10 @@ This makes it possible to write .. code-block:: pycon - >>> p = example.Pet('Molly') + >>> p = example.Pet("Molly") >>> p.name u'Molly' - >>> p.name = 'Charly' + >>> p.name = "Charly" >>> p.name u'Charly' @@ -174,10 +174,10 @@ Native Python classes can pick up new attributes dynamically: .. code-block:: pycon >>> class Pet: - ... name = 'Molly' + ... name = "Molly" ... >>> p = Pet() - >>> p.name = 'Charly' # overwrite existing + >>> p.name = "Charly" # overwrite existing >>> p.age = 2 # dynamically add a new attribute By default, classes exported from C++ do not support this and the only writable @@ -195,7 +195,7 @@ Trying to set any other attribute results in an error: .. code-block:: pycon >>> p = example.Pet() - >>> p.name = 'Charly' # OK, attribute defined in C++ + >>> p.name = "Charly" # OK, attribute defined in C++ >>> p.age = 2 # fail AttributeError: 'Pet' object has no attribute 'age' @@ -213,7 +213,7 @@ Now everything works as expected: .. code-block:: pycon >>> p = example.Pet() - >>> p.name = 'Charly' # OK, overwrite value in C++ + >>> p.name = "Charly" # OK, overwrite value in C++ >>> p.age = 2 # OK, dynamically add a new attribute >>> p.__dict__ # just like a native Python class {'age': 2} @@ -280,7 +280,7 @@ expose fields and methods of both types: .. code-block:: pycon - >>> p = example.Dog('Molly') + >>> p = example.Dog("Molly") >>> p.name u'Molly' >>> p.bark() @@ -486,7 +486,7 @@ typed enums. .. code-block:: pycon - >>> p = Pet('Lucy', Pet.Cat) + >>> p = Pet("Lucy", Pet.Cat) >>> p.type Kind.Cat >>> int(p.type) @@ -508,7 +508,7 @@ The ``name`` property returns the name of the enum value as a unicode string. .. code-block:: pycon - >>> p = Pet( "Lucy", Pet.Cat ) + >>> p = Pet("Lucy", Pet.Cat) >>> pet_type = p.type >>> pet_type Pet.Cat diff --git a/docs/compiling.rst b/docs/compiling.rst index eaf3270e0..073851048 100644 --- a/docs/compiling.rst +++ b/docs/compiling.rst @@ -42,10 +42,7 @@ An example of a ``setup.py`` using pybind11's helpers: ), ] - setup( - ..., - ext_modules=ext_modules - ) + setup(..., ext_modules=ext_modules) If you want to do an automatic search for the highest supported C++ standard, that is supported via a ``build_ext`` command override; it will only affect @@ -64,11 +61,7 @@ that is supported via a ``build_ext`` command override; it will only affect ), ] - setup( - ..., - cmdclass={"build_ext": build_ext}, - ext_modules=ext_modules - ) + setup(..., cmdclass={"build_ext": build_ext}, ext_modules=ext_modules) If you have single-file extension modules that are directly stored in the Python source tree (``foo.cpp`` in the same directory as where a ``foo.py`` diff --git a/docs/conf.py b/docs/conf.py index 458a86886..092e274e0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,7 +15,6 @@ import os import re -import shlex import subprocess import sys from pathlib import Path diff --git a/docs/faq.rst b/docs/faq.rst index d6a048b06..e2f477b1f 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -54,7 +54,7 @@ provided by the caller -- in fact, it does nothing at all. .. code-block:: python def increment(i): - i += 1 # nope.. + i += 1 # nope.. pybind11 is also affected by such language-level conventions, which means that binding ``increment`` or ``increment_ptr`` will also create Python functions