Skip to content

Commit 4b42c37

Browse files
authored
style: pylint (#3720)
* fix: add pylint and fix issue * chore: add pylint to pre-commit * fix: local variable warning surfaced mistake in intree
1 parent c14170a commit 4b42c37

File tree

9 files changed

+124
-33
lines changed

9 files changed

+124
-33
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docs/*.svg binary

.github/matchers/pylint.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"problemMatcher": [
3+
{
4+
"severity": "warning",
5+
"pattern": [
6+
{
7+
"regexp": "^([^:]+):(\\d+):(\\d+): ([A-DF-Z]\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
8+
"file": 1,
9+
"line": 2,
10+
"column": 3,
11+
"code": 4,
12+
"message": 5
13+
}
14+
],
15+
"owner": "pylint-warning"
16+
},
17+
{
18+
"severity": "error",
19+
"pattern": [
20+
{
21+
"regexp": "^([^:]+):(\\d+):(\\d+): (E\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
22+
"file": 1,
23+
"line": 2,
24+
"column": 3,
25+
"code": 4,
26+
"message": 5
27+
}
28+
],
29+
"owner": "pylint-error"
30+
}
31+
]
32+
}

.github/workflows/format.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ on:
1212
- stable
1313
- "v*"
1414

15+
env:
16+
FORCE_COLOR: 3
17+
1518
jobs:
1619
pre-commit:
1720
name: Format
1821
runs-on: ubuntu-latest
1922
steps:
2023
- uses: actions/checkout@v2
2124
- uses: actions/setup-python@v2
25+
- name: Add matchers
26+
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/matchers/pylint.json"
2227
- uses: pre-commit/[email protected]
2328
with:
2429
# Slow hooks are marked with manual - slow is okay here, run them too

.pre-commit-config.yaml

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,29 @@ repos:
8787
- id: rst-directive-colons
8888
- id: rst-inline-touching-normal
8989

90+
# Automatically remove noqa that are not used
91+
- repo: https://github.com/asottile/yesqa
92+
rev: "v1.3.0"
93+
hooks:
94+
- id: yesqa
95+
additional_dependencies: &flake8_dependencies
96+
- flake8-bugbear
97+
- pep8-naming
98+
9099
# Flake8 also supports pre-commit natively (same author)
91100
- repo: https://github.com/PyCQA/flake8
92101
rev: "4.0.1"
93102
hooks:
94103
- id: flake8
95-
additional_dependencies: &flake8_dependencies
96-
- flake8-bugbear
97-
- pep8-naming
98104
exclude: ^(docs/.*|tools/.*)$
105+
additional_dependencies: *flake8_dependencies
99106

100-
# Automatically remove noqa that are not used
101-
- repo: https://github.com/asottile/yesqa
102-
rev: "v1.3.0"
107+
# PyLint has native support - not always usable, but works for us
108+
- repo: https://github.com/PyCQA/pylint
109+
rev: "v2.12.2"
103110
hooks:
104-
- id: yesqa
105-
additional_dependencies: *flake8_dependencies
111+
- id: pylint
112+
files: ^pybind11
106113

107114
# CMake formatting
108115
- repo: https://github.com/cheshirekow/cmake-format-precommit

noxfile.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
import os
2+
13
import nox
24

35
nox.options.sessions = ["lint", "tests", "tests_packaging"]
46

5-
PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
7+
PYTHON_VERISONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy3.7", "pypy3.8"]
8+
9+
if os.environ.get("CI", None):
10+
nox.options.error_on_missing_interpreters = True
611

712

813
@nox.session(reuse_venv=True)
@@ -14,7 +19,7 @@ def lint(session: nox.Session) -> None:
1419
session.run("pre-commit", "run", "-a")
1520

1621

17-
@nox.session(python=PYTHON_VERSIONS)
22+
@nox.session(python=PYTHON_VERISONS)
1823
def tests(session: nox.Session) -> None:
1924
"""
2025
Run the tests (requires a compiler).

pybind11/__main__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# pylint: disable=missing-function-docstring
2+
13
import argparse
24
import sys
35
import sysconfig

pybind11/commands.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
DIR = os.path.abspath(os.path.dirname(__file__))
44

55

6-
def get_include(user: bool = False) -> str:
6+
def get_include(user: bool = False) -> str: # pylint: disable=unused-argument
7+
"""
8+
Return the path to the pybind11 include directory. The historical "user"
9+
argument is unused, and may be removed.
10+
"""
711
installed_path = os.path.join(DIR, "include")
812
source_path = os.path.join(os.path.dirname(DIR), "include")
913
return installed_path if os.path.exists(installed_path) else source_path
1014

1115

1216
def get_cmake_dir() -> str:
17+
"""
18+
Return the path to the pybind11 CMake module directory.
19+
"""
1320
cmake_installed_path = os.path.join(DIR, "share", "cmake", "pybind11")
1421
if os.path.exists(cmake_installed_path):
1522
return cmake_installed_path
16-
else:
17-
msg = "pybind11 not installed, installation required to access the CMake files"
18-
raise ImportError(msg)
23+
24+
msg = "pybind11 not installed, installation required to access the CMake files"
25+
raise ImportError(msg)

pybind11/setup_helpers.py

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def has_flag(compiler: Any, flag: str) -> bool:
239239
with tmp_chdir():
240240
fname = Path("flagcheck.cpp")
241241
# Don't trigger -Wunused-parameter.
242-
fname.write_text("int main (int, char **) { return 0; }")
242+
fname.write_text("int main (int, char **) { return 0; }", encoding="utf-8")
243243

244244
try:
245245
compiler.compile([str(fname)], extra_postargs=[flag])
@@ -303,29 +303,31 @@ def intree_extensions(
303303
"""
304304
exts = []
305305

306-
for path in paths:
307-
if package_dir is None:
306+
if package_dir is None:
307+
for path in paths:
308308
parent, _ = os.path.split(path)
309309
while os.path.exists(os.path.join(parent, "__init__.py")):
310310
parent, _ = os.path.split(parent)
311311
relname, _ = os.path.splitext(os.path.relpath(path, parent))
312312
qualified_name = relname.replace(os.path.sep, ".")
313313
exts.append(Pybind11Extension(qualified_name, [path]))
314+
return exts
315+
316+
for path in paths:
317+
for prefix, parent in package_dir.items():
318+
if path.startswith(parent):
319+
relname, _ = os.path.splitext(os.path.relpath(path, parent))
320+
qualified_name = relname.replace(os.path.sep, ".")
321+
if prefix:
322+
qualified_name = prefix + "." + qualified_name
323+
exts.append(Pybind11Extension(qualified_name, [path]))
324+
break
314325
else:
315-
for prefix, parent in package_dir.items():
316-
if path.startswith(parent):
317-
relname, _ = os.path.splitext(os.path.relpath(path, parent))
318-
qualified_name = relname.replace(os.path.sep, ".")
319-
if prefix:
320-
qualified_name = prefix + "." + qualified_name
321-
exts.append(Pybind11Extension(qualified_name, [path]))
322-
323-
if not exts:
324-
msg = (
325-
f"path {path} is not a child of any of the directories listed "
326-
f"in 'package_dir' ({package_dir})"
327-
)
328-
raise ValueError(msg)
326+
msg = (
327+
f"path {path} is not a child of any of the directories listed "
328+
f"in 'package_dir' ({package_dir})"
329+
)
330+
raise ValueError(msg)
329331

330332
return exts
331333

@@ -339,7 +341,7 @@ def naive_recompile(obj: str, src: str) -> bool:
339341
return os.stat(obj).st_mtime < os.stat(src).st_mtime
340342

341343

342-
def no_recompile(obg: str, src: str) -> bool:
344+
def no_recompile(obg: str, src: str) -> bool: # pylint: disable=unused-argument
343345
"""
344346
This is the safest but slowest choice (and is the default) - will always
345347
recompile sources.
@@ -412,7 +414,7 @@ def __init__(
412414
self,
413415
envvar: Optional[str] = None,
414416
default: int = 0,
415-
max: int = 0,
417+
max: int = 0, # pylint: disable=redefined-builtin
416418
needs_recompile: Callable[[str, str], bool] = no_recompile,
417419
) -> None:
418420
self.envvar = envvar
@@ -488,6 +490,9 @@ def _single_compile(obj: Any) -> None:
488490
return compile_function
489491

490492
def install(self: S) -> S:
493+
"""
494+
Installs the compile function into distutils.ccompiler.CCompiler.compile.
495+
"""
491496
distutils.ccompiler.CCompiler.compile = self.function() # type: ignore[assignment]
492497
return self
493498

pyproject.toml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,30 @@ strict = true
3030
[[tool.mypy.overrides]]
3131
module = ["ghapi.*", "setuptools.*"]
3232
ignore_missing_imports = true
33+
34+
35+
[tool.pytest.ini_options]
36+
minversion = "6.0"
37+
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
38+
xfail_strict = true
39+
filterwarnings = ["error"]
40+
log_cli_level = "info"
41+
testpaths = [
42+
"tests",
43+
]
44+
timeout=300
45+
46+
47+
[tool.pylint]
48+
master.py-version = "3.6"
49+
reports.output-format = "colorized"
50+
messages_control.disable = [
51+
"design",
52+
"fixme",
53+
"imports",
54+
"line-too-long",
55+
"imports",
56+
"invalid-name",
57+
"protected-access",
58+
"missing-module-docstring",
59+
]

0 commit comments

Comments
 (0)