mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-19 01:42:58 +01:00
lint: Speed up flake8 checks
Previously they may have taken more than 10 seconds. Now they should finish in less than one second. This also allows to drop one dependency to be installed.
This commit is contained in:
parent
faf17df7fb
commit
fafdb7df34
@ -49,7 +49,6 @@ fi
|
|||||||
|
|
||||||
${CI_RETRY_EXE} pip3 install \
|
${CI_RETRY_EXE} pip3 install \
|
||||||
codespell==2.2.6 \
|
codespell==2.2.6 \
|
||||||
flake8==6.1.0 \
|
|
||||||
lief==0.13.2 \
|
lief==0.13.2 \
|
||||||
mypy==1.4.1 \
|
mypy==1.4.1 \
|
||||||
pyzmq==25.1.0 \
|
pyzmq==25.1.0 \
|
||||||
|
@ -45,7 +45,6 @@ or `--help`:
|
|||||||
|
|
||||||
| Lint test | Dependency |
|
| Lint test | Dependency |
|
||||||
|-----------|:----------:|
|
|-----------|:----------:|
|
||||||
| [`lint-python.py`](/test/lint/lint-python.py) | [flake8](https://github.com/PyCQA/flake8)
|
|
||||||
| [`lint-python.py`](/test/lint/lint-python.py) | [lief](https://github.com/lief-project/LIEF)
|
| [`lint-python.py`](/test/lint/lint-python.py) | [lief](https://github.com/lief-project/LIEF)
|
||||||
| [`lint-python.py`](/test/lint/lint-python.py) | [mypy](https://github.com/python/mypy)
|
| [`lint-python.py`](/test/lint/lint-python.py) | [mypy](https://github.com/python/mypy)
|
||||||
| [`lint-python.py`](/test/lint/lint-python.py) | [pyzmq](https://github.com/zeromq/pyzmq)
|
| [`lint-python.py`](/test/lint/lint-python.py) | [pyzmq](https://github.com/zeromq/pyzmq)
|
||||||
|
@ -5,13 +5,12 @@
|
|||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Check for specified flake8 and mypy warnings in python files.
|
Check for specified mypy warnings in python files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
|
|
||||||
from importlib.metadata import metadata, PackageNotFoundError
|
from importlib.metadata import metadata, PackageNotFoundError
|
||||||
|
|
||||||
@ -19,52 +18,12 @@ from importlib.metadata import metadata, PackageNotFoundError
|
|||||||
cache_dir = Path(__file__).parent.parent / ".mypy_cache"
|
cache_dir = Path(__file__).parent.parent / ".mypy_cache"
|
||||||
os.environ["MYPY_CACHE_DIR"] = str(cache_dir)
|
os.environ["MYPY_CACHE_DIR"] = str(cache_dir)
|
||||||
|
|
||||||
DEPS = ['flake8', 'lief', 'mypy', 'pyzmq']
|
DEPS = ['lief', 'mypy', 'pyzmq']
|
||||||
|
|
||||||
# All .py files, except those in src/ (to exclude subtrees there)
|
|
||||||
FLAKE_FILES_ARGS = ['git', 'ls-files', '*.py', ':!:src/*.py']
|
|
||||||
|
|
||||||
# Only .py files in test/functional and contrib/devtools have type annotations
|
# Only .py files in test/functional and contrib/devtools have type annotations
|
||||||
# enforced.
|
# enforced.
|
||||||
MYPY_FILES_ARGS = ['git', 'ls-files', 'test/functional/*.py', 'contrib/devtools/*.py']
|
MYPY_FILES_ARGS = ['git', 'ls-files', 'test/functional/*.py', 'contrib/devtools/*.py']
|
||||||
|
|
||||||
ENABLED = (
|
|
||||||
'E101,' # indentation contains mixed spaces and tabs
|
|
||||||
'E401,' # multiple imports on one line
|
|
||||||
'E402,' # module level import not at top of file
|
|
||||||
'E701,' # multiple statements on one line (colon)
|
|
||||||
'E702,' # multiple statements on one line (semicolon)
|
|
||||||
'E703,' # statement ends with a semicolon
|
|
||||||
'E711,' # comparison to None should be 'if cond is None:'
|
|
||||||
'E714,' # test for object identity should be "is not"
|
|
||||||
'E721,' # do not compare types, use "isinstance()"
|
|
||||||
'E722,' # do not use bare 'except'
|
|
||||||
'E742,' # do not define classes named "l", "O", or "I"
|
|
||||||
'E743,' # do not define functions named "l", "O", or "I"
|
|
||||||
'F401,' # module imported but unused
|
|
||||||
'F402,' # import module from line N shadowed by loop variable
|
|
||||||
'F403,' # 'from foo_module import *' used; unable to detect undefined names
|
|
||||||
'F404,' # future import(s) name after other statements
|
|
||||||
'F405,' # foo_function may be undefined, or defined from star imports: bar_module
|
|
||||||
'F406,' # "from module import *" only allowed at module level
|
|
||||||
'F407,' # an undefined __future__ feature name was imported
|
|
||||||
'F601,' # dictionary key name repeated with different values
|
|
||||||
'F602,' # dictionary key variable name repeated with different values
|
|
||||||
'F621,' # too many expressions in an assignment with star-unpacking
|
|
||||||
'F631,' # assertion test is a tuple, which are always True
|
|
||||||
'F632,' # use ==/!= to compare str, bytes, and int literals
|
|
||||||
'F811,' # redefinition of unused name from line N
|
|
||||||
'F821,' # undefined name 'Foo'
|
|
||||||
'F822,' # undefined name name in __all__
|
|
||||||
'F823,' # local variable name … referenced before assignment
|
|
||||||
'F841,' # local variable 'foo' is assigned to but never used
|
|
||||||
'W191,' # indentation contains tabs
|
|
||||||
'W291,' # trailing whitespace
|
|
||||||
'W292,' # no newline at end of file
|
|
||||||
'W293,' # blank line contains whitespace
|
|
||||||
'W605,' # invalid escape sequence "x"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def check_dependencies():
|
def check_dependencies():
|
||||||
for dep in DEPS:
|
for dep in DEPS:
|
||||||
@ -78,20 +37,6 @@ def check_dependencies():
|
|||||||
def main():
|
def main():
|
||||||
check_dependencies()
|
check_dependencies()
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
|
||||||
flake8_files = sys.argv[1:]
|
|
||||||
else:
|
|
||||||
flake8_files = subprocess.check_output(FLAKE_FILES_ARGS).decode("utf-8").splitlines()
|
|
||||||
|
|
||||||
flake8_args = ['flake8', '--ignore=B,C,E,F,I,N,W', f'--select={ENABLED}'] + flake8_files
|
|
||||||
flake8_env = os.environ.copy()
|
|
||||||
flake8_env["PYTHONWARNINGS"] = "ignore"
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.check_call(flake8_args, env=flake8_env)
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
mypy_files = subprocess.check_output(MYPY_FILES_ARGS).decode("utf-8").splitlines()
|
mypy_files = subprocess.check_output(MYPY_FILES_ARGS).decode("utf-8").splitlines()
|
||||||
mypy_args = ['mypy', '--show-error-codes'] + mypy_files
|
mypy_args = ['mypy', '--show-error-codes'] + mypy_files
|
||||||
|
|
||||||
|
@ -187,10 +187,48 @@ fn lint_subtree() -> LintResult {
|
|||||||
|
|
||||||
fn lint_py_lint() -> LintResult {
|
fn lint_py_lint() -> LintResult {
|
||||||
let bin_name = "ruff";
|
let bin_name = "ruff";
|
||||||
let checks = ["B006", "B008"]
|
let checks = format!(
|
||||||
.iter()
|
"--select={}",
|
||||||
.map(|c| format!("--select={}", c))
|
[
|
||||||
.collect::<Vec<_>>();
|
"B006", // mutable-argument-default
|
||||||
|
"B008", // function-call-in-default-argument
|
||||||
|
"E101", // indentation contains mixed spaces and tabs
|
||||||
|
"E401", // multiple imports on one line
|
||||||
|
"E402", // module level import not at top of file
|
||||||
|
"E701", // multiple statements on one line (colon)
|
||||||
|
"E702", // multiple statements on one line (semicolon)
|
||||||
|
"E703", // statement ends with a semicolon
|
||||||
|
"E711", // comparison to None should be 'if cond is None:'
|
||||||
|
"E714", // test for object identity should be "is not"
|
||||||
|
"E721", // do not compare types, use "isinstance()"
|
||||||
|
"E722", // do not use bare 'except'
|
||||||
|
"E742", // do not define classes named "l", "O", or "I"
|
||||||
|
"E743", // do not define functions named "l", "O", or "I"
|
||||||
|
"F401", // module imported but unused
|
||||||
|
"F402", // import module from line N shadowed by loop variable
|
||||||
|
"F403", // 'from foo_module import *' used; unable to detect undefined names
|
||||||
|
"F404", // future import(s) name after other statements
|
||||||
|
"F405", // foo_function may be undefined, or defined from star imports: bar_module
|
||||||
|
"F406", // "from module import *" only allowed at module level
|
||||||
|
"F407", // an undefined __future__ feature name was imported
|
||||||
|
"F601", // dictionary key name repeated with different values
|
||||||
|
"F602", // dictionary key variable name repeated with different values
|
||||||
|
"F621", // too many expressions in an assignment with star-unpacking
|
||||||
|
"F631", // assertion test is a tuple, which are always True
|
||||||
|
"F632", // use ==/!= to compare str, bytes, and int literals
|
||||||
|
"F811", // redefinition of unused name from line N
|
||||||
|
"F821", // undefined name 'Foo'
|
||||||
|
"F822", // undefined name name in __all__
|
||||||
|
"F823", // local variable name … referenced before assignment
|
||||||
|
"F841", // local variable 'foo' is assigned to but never used
|
||||||
|
"W191", // indentation contains tabs
|
||||||
|
"W291", // trailing whitespace
|
||||||
|
"W292", // no newline at end of file
|
||||||
|
"W293", // blank line contains whitespace
|
||||||
|
"W605", // invalid escape sequence "x"
|
||||||
|
]
|
||||||
|
.join(",")
|
||||||
|
);
|
||||||
let files = check_output(
|
let files = check_output(
|
||||||
git()
|
git()
|
||||||
.args(["ls-files", "--", "*.py"])
|
.args(["ls-files", "--", "*.py"])
|
||||||
@ -198,7 +236,7 @@ fn lint_py_lint() -> LintResult {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut cmd = Command::new(bin_name);
|
let mut cmd = Command::new(bin_name);
|
||||||
cmd.arg("check").args(checks).args(files.lines());
|
cmd.args(["check", &checks]).args(files.lines());
|
||||||
|
|
||||||
match cmd.status() {
|
match cmd.status() {
|
||||||
Ok(status) if status.success() => Ok(()),
|
Ok(status) if status.success() => Ok(()),
|
||||||
|
Loading…
Reference in New Issue
Block a user