Add blacken-docs and pycln pre-commit hooks (#3292)

* Apply blacken-docs and fix language-hints

* Add blacken-docs pre-commit hook

* Add pycln pre-commit hook

* Enable a few builtin hooks

* Black no longer ignores pyi files
This commit is contained in:
Aaron Gokaslan 2021-09-22 15:38:50 -04:00 committed by GitHub
parent ee0c5ee405
commit 0fb981b219
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 72 additions and 60 deletions

View File

@ -19,8 +19,10 @@ repos:
hooks: hooks:
- id: check-added-large-files - id: check-added-large-files
- id: check-case-conflict - id: check-case-conflict
- id: check-docstring-first
- id: check-merge-conflict - id: check-merge-conflict
- id: check-symlinks - id: check-symlinks
- id: check-toml
- id: check-yaml - id: check-yaml
- id: debug-statements - id: debug-statements
- id: end-of-file-fixer - id: end-of-file-fixer
@ -42,12 +44,16 @@ repos:
# Black, the code formatter, natively supports pre-commit # Black, the code formatter, natively supports pre-commit
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 21.9b0 rev: 21.9b0 # Keep in sync with blacken-docs
hooks: hooks:
- id: black - id: black
# By default, this ignores pyi files, though black supports them
types: [text] - repo: https://github.com/asottile/blacken-docs
files: \.pyi?$ rev: v1.11.0
hooks:
- id: blacken-docs
additional_dependencies:
- black==21.9b0 # keep in sync with black hook
# Changes tabs to spaces # Changes tabs to spaces
- repo: https://github.com/Lucas-C/pre-commit-hooks - repo: https://github.com/Lucas-C/pre-commit-hooks
@ -55,6 +61,12 @@ repos:
hooks: hooks:
- id: remove-tabs - 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) # Flake8 also supports pre-commit natively (same author)
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: 3.9.2 rev: 3.9.2
@ -86,7 +98,7 @@ repos:
# Checks the manifest for missing files (native support) # Checks the manifest for missing files (native support)
- repo: https://github.com/mgedmin/check-manifest - repo: https://github.com/mgedmin/check-manifest
rev: "0.46" rev: "0.47"
hooks: hooks:
- id: check-manifest - id: check-manifest
# This is a slow hook, so only run this if --hook-stage manual is passed # This is a slow hook, so only run this if --hook-stage manual is passed
@ -100,10 +112,10 @@ repos:
exclude: ".supp$" exclude: ".supp$"
args: ["-L", "nd,ot,thist"] args: ["-L", "nd,ot,thist"]
- repo: https://github.com/shellcheck-py/shellcheck-py - repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.7.2.1 rev: v0.7.2.1
hooks: hooks:
- id: shellcheck - id: shellcheck
# The original pybind11 checks for a few C++ style items # The original pybind11 checks for a few C++ style items
- repo: local - repo: local

View File

@ -26,7 +26,9 @@ The following Python snippet demonstrates the intended usage from the Python sid
def __int__(self): def __int__(self):
return 123 return 123
from example import print from example import print
print(A()) print(A())
To register the necessary conversion routines, it is necessary to add an To register the necessary conversion routines, it is necessary to add an

View File

@ -112,7 +112,7 @@ example:
.. code-block:: python .. code-block:: python
a = MyClass() 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 v = a.view_matrix() # flags.writeable = False, flags.owndata = False
c = a.copy_matrix() # flags.writeable = True, flags.owndata = True 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. # 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 .. 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 Such an object will be passable to a bound function accepting an
``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type). ``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type).

View File

@ -36,13 +36,13 @@ everywhere <http://utf8everywhere.org/>`_.
} }
); );
.. code-block:: python .. code-block:: pycon
>>> utf8_test('🎂') >>> utf8_test("🎂")
utf-8 is icing on the cake. utf-8 is icing on the cake.
🎂 🎂
>>> utf8_charptr('🍕') >>> utf8_charptr("🍕")
My favorite food is My favorite food is
🍕 🍕
@ -80,7 +80,7 @@ raise a ``UnicodeDecodeError``.
} }
); );
.. code-block:: python .. code-block:: pycon
>>> isinstance(example.std_string_return(), str) >>> isinstance(example.std_string_return(), str)
True True
@ -114,7 +114,7 @@ conversion has the same overhead as implicit conversion.
} }
); );
.. code-block:: python .. code-block:: pycon
>>> str_output() >>> str_output()
'Send your résumé to Alice in HR' '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() >>> example.return_bytes()
b'\xba\xd0\xba\xd0' 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) >>> isinstance(example.asymmetry(b"have some bytes"), str)
True True
@ -229,16 +229,16 @@ character.
m.def("pass_char", [](char c) { return c; }); m.def("pass_char", [](char c) { return c; });
m.def("pass_wchar", [](wchar_t w) { return w; }); m.def("pass_wchar", [](wchar_t w) { return w; });
.. code-block:: python .. code-block:: pycon
>>> example.pass_char('A') >>> example.pass_char("A")
'A' 'A'
While C++ will cast integers to character types (``char c = 0x65;``), pybind11 While C++ will cast integers to character types (``char c = 0x65;``), pybind11
does not convert Python integers to characters implicitly. The Python function does not convert Python integers to characters implicitly. The Python function
``chr()`` can be used to convert integers to characters. ``chr()`` can be used to convert integers to characters.
.. code-block:: python .. code-block:: pycon
>>> example.pass_char(0x65) >>> example.pass_char(0x65)
TypeError 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 two-character sequence is passed as an argument, even though it renders as a
single grapheme. 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 == 'é' >>> combining_e_acute == "é"
False False
>>> example.pass_wchar(combining_e_acute) >>> example.pass_wchar(combining_e_acute)
@ -278,9 +278,9 @@ single grapheme.
Normalizing combining characters before passing the character literal to C++ Normalizing combining characters before passing the character literal to C++
may resolve *some* of these issues: 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 In some languages (Thai for example), there are `graphemes that cannot be

View File

@ -136,7 +136,7 @@ a virtual method call.
u'woof! woof! woof! ' u'woof! woof! woof! '
>>> class Cat(Animal): >>> class Cat(Animal):
... def go(self, n_times): ... def go(self, n_times):
... return "meow! " * n_times ... return "meow! " * n_times
... ...
>>> c = Cat() >>> c = Cat()
>>> call_go(c) >>> call_go(c)
@ -159,8 +159,9 @@ Here is an example:
class Dachshund(Dog): class Dachshund(Dog):
def __init__(self, name): 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 self.name = name
def bark(self): def bark(self):
return "yap!" return "yap!"
@ -1153,6 +1154,7 @@ error:
>>> class PyFinalChild(IsFinal): >>> class PyFinalChild(IsFinal):
... pass ... pass
...
TypeError: type 'IsFinal' is not an acceptable base type TypeError: type 'IsFinal' is not an acceptable base type
.. note:: This attribute is currently ignored on PyPy .. 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: 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<T>(); py::type T_py = py::type::of<T>();

View File

@ -122,6 +122,7 @@ embedding the interpreter. This makes it easy to import local Python files:
"""calc.py located in the working directory""" """calc.py located in the working directory"""
def add(i, j): def add(i, j):
return i + j return i + j

View File

@ -272,7 +272,7 @@ And used in Python as usual:
.. code-block:: pycon .. code-block:: pycon
>>> print_dict({'foo': 123, 'bar': 'hello'}) >>> print_dict({"foo": 123, "bar": "hello"})
key=foo, value=123 key=foo, value=123
key=bar, value=hello 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 def f(a, *, b): # a can be positional or via keyword; b must be via keyword
pass pass
f(a=1, b=2) # good f(a=1, b=2) # good
f(b=2, a=1) # good f(b=2, a=1) # good
f(1, b=2) # good f(1, b=2) # good
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given 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 Pybind11 provides a ``py::kw_only`` object that allows you to implement
the same behaviour by specifying the object between positional and keyword-only the same behaviour by specifying the object between positional and keyword-only

View File

@ -258,8 +258,8 @@ by the compiler. The result is returned as a NumPy array of type
.. code-block:: pycon .. code-block:: pycon
>>> x = np.array([[1, 3],[5, 7]]) >>> x = np.array([[1, 3], [5, 7]])
>>> y = np.array([[2, 4],[6, 8]]) >>> y = np.array([[2, 4], [6, 8]])
>>> z = 3 >>> z = 3
>>> result = vectorized_func(x, y, z) >>> 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 .. code-block:: python
a = # a NumPy array a = ... # a NumPy array
b = a[0, ..., 0] b = a[0, ..., 0]
The function ``py::ellipsis()`` function can be used to perform the same The function ``py::ellipsis()`` function can be used to perform the same

View File

@ -173,6 +173,7 @@ Keyword arguments are also supported. In Python, there is the usual call syntax:
def f(number, say, to): def f(number, say, to):
... # function code ... # function code
f(1234, say="hello", to=some_instance) # keyword call in Python f(1234, say="hello", to=some_instance) # keyword call in Python
In C++, the same call can be made using: In C++, the same call can be made using:

View File

@ -66,7 +66,7 @@ extra type, `py::scoped_estream_redirect <scoped_estream_redirect>`, is identica
except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with 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:: py .. code-block:: cpp
// Alternative: Call single function using call guard // Alternative: Call single function using call guard
m.def("noisy_func", &call_noisy_function, m.def("noisy_func", &call_noisy_function,

View File

@ -77,6 +77,7 @@ segmentation fault).
.. code-block:: python .. code-block:: python
from example import Parent from example import Parent
print(Parent().get_child()) print(Parent().get_child())
The problem is that ``Parent::get_child()`` returns a pointer to an instance of The problem is that ``Parent::get_child()`` returns a pointer to an instance of

View File

@ -2,7 +2,6 @@
import datetime as dt import datetime as dt
import os import os
import random import random
import time
nfns = 4 # Functions per class nfns = 4 # Functions per class
nargs = 4 # Arguments per function nargs = 4 # Arguments per function

View File

@ -1142,6 +1142,7 @@ v2.2.0 (August 31, 2017)
from cpp_module import CppBase1, CppBase2 from cpp_module import CppBase1, CppBase2
class PyDerived(CppBase1, CppBase2): class PyDerived(CppBase1, CppBase2):
def __init__(self): def __init__(self):
CppBase1.__init__(self) # C++ bases must be initialized explicitly CppBase1.__init__(self) # C++ bases must be initialized explicitly

View File

@ -44,12 +44,12 @@ interactive Python session demonstrating this example is shown below:
% python % python
>>> import example >>> import example
>>> p = example.Pet('Molly') >>> p = example.Pet("Molly")
>>> print(p) >>> print(p)
<example.Pet object at 0x10cd98060> <example.Pet object at 0x10cd98060>
>>> p.getName() >>> p.getName()
u'Molly' u'Molly'
>>> p.setName('Charly') >>> p.setName("Charly")
>>> p.getName() >>> p.getName()
u'Charly' u'Charly'
@ -122,10 +122,10 @@ This makes it possible to write
.. code-block:: pycon .. code-block:: pycon
>>> p = example.Pet('Molly') >>> p = example.Pet("Molly")
>>> p.name >>> p.name
u'Molly' u'Molly'
>>> p.name = 'Charly' >>> p.name = "Charly"
>>> p.name >>> p.name
u'Charly' u'Charly'
@ -174,10 +174,10 @@ Native Python classes can pick up new attributes dynamically:
.. code-block:: pycon .. code-block:: pycon
>>> class Pet: >>> class Pet:
... name = 'Molly' ... name = "Molly"
... ...
>>> p = Pet() >>> p = Pet()
>>> p.name = 'Charly' # overwrite existing >>> p.name = "Charly" # overwrite existing
>>> p.age = 2 # dynamically add a new attribute >>> p.age = 2 # dynamically add a new attribute
By default, classes exported from C++ do not support this and the only writable 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 .. code-block:: pycon
>>> p = example.Pet() >>> p = example.Pet()
>>> p.name = 'Charly' # OK, attribute defined in C++ >>> p.name = "Charly" # OK, attribute defined in C++
>>> p.age = 2 # fail >>> p.age = 2 # fail
AttributeError: 'Pet' object has no attribute 'age' AttributeError: 'Pet' object has no attribute 'age'
@ -213,7 +213,7 @@ Now everything works as expected:
.. code-block:: pycon .. code-block:: pycon
>>> p = example.Pet() >>> 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.age = 2 # OK, dynamically add a new attribute
>>> p.__dict__ # just like a native Python class >>> p.__dict__ # just like a native Python class
{'age': 2} {'age': 2}
@ -280,7 +280,7 @@ expose fields and methods of both types:
.. code-block:: pycon .. code-block:: pycon
>>> p = example.Dog('Molly') >>> p = example.Dog("Molly")
>>> p.name >>> p.name
u'Molly' u'Molly'
>>> p.bark() >>> p.bark()
@ -486,7 +486,7 @@ typed enums.
.. code-block:: pycon .. code-block:: pycon
>>> p = Pet('Lucy', Pet.Cat) >>> p = Pet("Lucy", Pet.Cat)
>>> p.type >>> p.type
Kind.Cat Kind.Cat
>>> int(p.type) >>> int(p.type)
@ -508,7 +508,7 @@ The ``name`` property returns the name of the enum value as a unicode string.
.. code-block:: pycon .. code-block:: pycon
>>> p = Pet( "Lucy", Pet.Cat ) >>> p = Pet("Lucy", Pet.Cat)
>>> pet_type = p.type >>> pet_type = p.type
>>> pet_type >>> pet_type
Pet.Cat Pet.Cat

View File

@ -42,10 +42,7 @@ An example of a ``setup.py`` using pybind11's helpers:
), ),
] ]
setup( setup(..., ext_modules=ext_modules)
...,
ext_modules=ext_modules
)
If you want to do an automatic search for the highest supported C++ standard, 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 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( setup(..., cmdclass={"build_ext": build_ext}, ext_modules=ext_modules)
...,
cmdclass={"build_ext": build_ext},
ext_modules=ext_modules
)
If you have single-file extension modules that are directly stored in the 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`` Python source tree (``foo.cpp`` in the same directory as where a ``foo.py``

View File

@ -15,7 +15,6 @@
import os import os
import re import re
import shlex
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path

View File

@ -54,7 +54,7 @@ provided by the caller -- in fact, it does nothing at all.
.. code-block:: python .. code-block:: python
def increment(i): def increment(i):
i += 1 # nope.. i += 1 # nope..
pybind11 is also affected by such language-level conventions, which means that pybind11 is also affected by such language-level conventions, which means that
binding ``increment`` or ``increment_ptr`` will also create Python functions binding ``increment`` or ``increment_ptr`` will also create Python functions