mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 11:27:28 -03:00
Merge bitcoin/bitcoin#30723: lint: Speed up and fix flake8 checks
fafdb7df34
lint: Speed up flake8 checks (MarcoFalke)faf17df7fb
lint: Document missing py_lint dependency (MarcoFalke)faebeb828f
lint: Remove python whitespace and shadowing lint rules (MarcoFalke)7777047835
lint: Remove python lint rules that are SyntaxError (MarcoFalke)faaf3e53f0
test: [refactor] Fix F841 flake8 (MarcoFalke)444421db69
test: [refactor] Fix E714 pycodestyle (MarcoFalke) Pull request description: The checks have many issues: * Some checks that could in theory hide bugs are not applied -> Fix them and apply them going forward * Some checks are redundant Python 2 checks, or of low value -> Remove them * The checks are slow -> Speed them up from ~10 seconds to about ~20 milliseconds ACKs for top commit: davidgumberg: review and tested reACKfafdb7df34
kevkevinpal: ACK [fafdb7d
](fafdb7df34
) achow101: ACKfafdb7df34
Tree-SHA512: a0488b722cfaf7071bd6848cd3be002e0b6c38af80d8b5cbb08613c0b174ef63277289f960db8ac31adb09fe563a4973203b8fb10b83cbcfdc6f0ef39bd04410
This commit is contained in:
commit
f640b323bd
13 changed files with 80 additions and 135 deletions
|
@ -48,7 +48,6 @@ fi
|
|||
|
||||
${CI_RETRY_EXE} pip3 install \
|
||||
codespell==2.2.6 \
|
||||
flake8==6.1.0 \
|
||||
lief==0.13.2 \
|
||||
mypy==1.4.1 \
|
||||
pyzmq==25.1.0 \
|
||||
|
|
|
@ -164,7 +164,7 @@ def main():
|
|||
'Failed to run "%s" - %s"' % (" ".join(command), e.strerror)
|
||||
)
|
||||
|
||||
stdout, stderr = p.communicate()
|
||||
stdout, _stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
sys.exit(p.returncode)
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ class CoinSelectionTracepointTest(BitcoinTestFramework):
|
|||
# 5. aps_create_tx_internal (type 4)
|
||||
wallet.sendtoaddress(wallet.getnewaddress(), 10)
|
||||
events = self.get_tracepoints([1, 2, 3, 1, 4])
|
||||
success, use_aps, algo, waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
success, use_aps, _algo, _waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
assert_equal(success, True)
|
||||
assert_greater_than(change_pos, -1)
|
||||
|
||||
|
@ -190,7 +190,7 @@ class CoinSelectionTracepointTest(BitcoinTestFramework):
|
|||
# 1. normal_create_tx_internal (type 2)
|
||||
assert_raises_rpc_error(-6, "Insufficient funds", wallet.sendtoaddress, wallet.getnewaddress(), 102 * 50)
|
||||
events = self.get_tracepoints([2])
|
||||
success, use_aps, algo, waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
success, use_aps, _algo, _waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
assert_equal(success, False)
|
||||
|
||||
self.log.info("Explicitly enabling APS results in 2 tracepoints")
|
||||
|
@ -200,7 +200,7 @@ class CoinSelectionTracepointTest(BitcoinTestFramework):
|
|||
wallet.setwalletflag("avoid_reuse")
|
||||
wallet.sendtoaddress(address=wallet.getnewaddress(), amount=10, avoid_reuse=True)
|
||||
events = self.get_tracepoints([1, 2])
|
||||
success, use_aps, algo, waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
success, use_aps, _algo, _waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
assert_equal(success, True)
|
||||
assert_equal(use_aps, None)
|
||||
|
||||
|
@ -213,7 +213,7 @@ class CoinSelectionTracepointTest(BitcoinTestFramework):
|
|||
# 5. aps_create_tx_internal (type 4)
|
||||
wallet.sendtoaddress(address=wallet.getnewaddress(), amount=wallet.getbalance(), subtractfeefromamount=True, avoid_reuse=False)
|
||||
events = self.get_tracepoints([1, 2, 3, 1, 4])
|
||||
success, use_aps, algo, waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
success, use_aps, _algo, _waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
assert_equal(success, True)
|
||||
assert_equal(change_pos, -1)
|
||||
|
||||
|
@ -223,7 +223,7 @@ class CoinSelectionTracepointTest(BitcoinTestFramework):
|
|||
# 2. normal_create_tx_internal (type 2)
|
||||
wallet.sendtoaddress(address=wallet.getnewaddress(), amount=wallet.getbalance(), subtractfeefromamount=True)
|
||||
events = self.get_tracepoints([1, 2])
|
||||
success, use_aps, algo, waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
success, use_aps, _algo, _waste, change_pos = self.determine_selection_from_usdt(events)
|
||||
assert_equal(success, True)
|
||||
assert_equal(change_pos, -1)
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ class PackageRBFTest(BitcoinTestFramework):
|
|||
package_hex4, package_txns4 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE)
|
||||
node.submitpackage(package_hex4)
|
||||
self.assert_mempool_contents(expected=package_txns4)
|
||||
package_hex5, package_txns5 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE, child_fee=DEFAULT_CHILD_FEE)
|
||||
package_hex5, _package_txns5 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE, child_fee=DEFAULT_CHILD_FEE)
|
||||
pkg_results5 = node.submitpackage(package_hex5)
|
||||
assert 'package RBF failed: package feerate is less than or equal to parent feerate' in pkg_results5["package_msg"]
|
||||
self.assert_mempool_contents(expected=package_txns4)
|
||||
|
@ -336,16 +336,16 @@ class PackageRBFTest(BitcoinTestFramework):
|
|||
self.assert_mempool_contents(expected=expected_txns)
|
||||
|
||||
# Now make conflicting packages for each coin
|
||||
package_hex1, package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex1, _package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
|
||||
package_result = node.submitpackage(package_hex1)
|
||||
assert_equal(f"package RBF failed: {parent_result['tx'].rehash()} has 2 descendants, max 1 allowed", package_result["package_msg"])
|
||||
|
||||
package_hex2, package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex2, _package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex2)
|
||||
assert_equal(f"package RBF failed: {child_result['tx'].rehash()} has both ancestor and descendant, exceeding cluster limit of 2", package_result["package_msg"])
|
||||
|
||||
package_hex3, package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex3, _package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex3)
|
||||
assert_equal(f"package RBF failed: {grandchild_result['tx'].rehash()} has 2 ancestors, max 1 allowed", package_result["package_msg"])
|
||||
|
||||
|
@ -389,15 +389,15 @@ class PackageRBFTest(BitcoinTestFramework):
|
|||
self.assert_mempool_contents(expected=expected_txns)
|
||||
|
||||
# Now make conflicting packages for each coin
|
||||
package_hex1, package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex1, _package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex1)
|
||||
assert_equal(f"package RBF failed: {parent1_result['tx'].rehash()} is not the only parent of child {child_result['tx'].rehash()}", package_result["package_msg"])
|
||||
|
||||
package_hex2, package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex2, _package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex2)
|
||||
assert_equal(f"package RBF failed: {parent2_result['tx'].rehash()} is not the only parent of child {child_result['tx'].rehash()}", package_result["package_msg"])
|
||||
|
||||
package_hex3, package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex3, _package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex3)
|
||||
assert_equal(f"package RBF failed: {child_result['tx'].rehash()} has 2 ancestors, max 1 allowed", package_result["package_msg"])
|
||||
|
||||
|
@ -443,15 +443,15 @@ class PackageRBFTest(BitcoinTestFramework):
|
|||
self.assert_mempool_contents(expected=expected_txns)
|
||||
|
||||
# Now make conflicting packages for each coin
|
||||
package_hex1, package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex1, _package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex1)
|
||||
assert_equal(f"package RBF failed: {parent_result['tx'].rehash()} has 2 descendants, max 1 allowed", package_result["package_msg"])
|
||||
|
||||
package_hex2, package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex2, _package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex2)
|
||||
assert_equal(f"package RBF failed: {child1_result['tx'].rehash()} is not the only child of parent {parent_result['tx'].rehash()}", package_result["package_msg"])
|
||||
|
||||
package_hex3, package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_hex3, _package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE)
|
||||
package_result = node.submitpackage(package_hex3)
|
||||
assert_equal(f"package RBF failed: {child2_result['tx'].rehash()} is not the only child of parent {parent_result['tx'].rehash()}", package_result["package_msg"])
|
||||
|
||||
|
@ -519,7 +519,7 @@ class PackageRBFTest(BitcoinTestFramework):
|
|||
|
||||
# Package 2 feerate is below the feerate of directly conflicted parent, so it fails even though
|
||||
# total fees are higher than the original package
|
||||
package_hex2, package_txns2 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE - Decimal("0.00000001"), child_fee=DEFAULT_CHILD_FEE)
|
||||
package_hex2, _package_txns2 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE - Decimal("0.00000001"), child_fee=DEFAULT_CHILD_FEE)
|
||||
pkg_results2 = node.submitpackage(package_hex2)
|
||||
assert_equal(pkg_results2["package_msg"], 'package RBF failed: insufficient feerate: does not improve feerate diagram')
|
||||
self.assert_mempool_contents(expected=package_txns1)
|
||||
|
|
|
@ -154,7 +154,7 @@ class BytesPerSigOpTest(BitcoinTestFramework):
|
|||
return (tx_utxo, tx)
|
||||
|
||||
tx_parent_utxo, tx_parent = create_bare_multisig_tx()
|
||||
tx_child_utxo, tx_child = create_bare_multisig_tx(tx_parent_utxo)
|
||||
_tx_child_utxo, tx_child = create_bare_multisig_tx(tx_parent_utxo)
|
||||
|
||||
# Separately, the parent tx is ok
|
||||
parent_individual_testres = self.nodes[0].testmempoolaccept([tx_parent.serialize().hex()])[0]
|
||||
|
|
|
@ -107,7 +107,7 @@ class PackageRelayTest(BitcoinTestFramework):
|
|||
|
||||
# 3: 2-parent-1-child package. Both parents are above mempool min feerate. No package submission happens.
|
||||
# We require packages to be child-with-unconfirmed-parents and only allow 1-parent-1-child packages.
|
||||
package_hex_3, parent_31, parent_32, child_3 = self.create_package_2p1c(self.wallet)
|
||||
package_hex_3, parent_31, _parent_32, child_3 = self.create_package_2p1c(self.wallet)
|
||||
|
||||
# 4: parent + child package where the child spends 2 different outputs from the parent.
|
||||
package_hex_4, parent_4, child_4 = self.create_package_2outs(self.wallet)
|
||||
|
|
|
@ -156,9 +156,9 @@ class TxDownloadTest(BitcoinTestFramework):
|
|||
# One of the peers is asked for the tx
|
||||
peer2.wait_until(lambda: sum(p.tx_getdata_count for p in [peer1, peer2]) == 1)
|
||||
with p2p_lock:
|
||||
peer_expiry, peer_fallback = (peer1, peer2) if peer1.tx_getdata_count == 1 else (peer2, peer1)
|
||||
_peer_expiry, peer_fallback = (peer1, peer2) if peer1.tx_getdata_count == 1 else (peer2, peer1)
|
||||
assert_equal(peer_fallback.tx_getdata_count, 0)
|
||||
self.nodes[0].setmocktime(int(time.time()) + GETDATA_TX_INTERVAL + 1) # Wait for request to peer_expiry to expire
|
||||
self.nodes[0].setmocktime(int(time.time()) + GETDATA_TX_INTERVAL + 1) # Wait for request to _peer_expiry to expire
|
||||
peer_fallback.wait_until(lambda: peer_fallback.tx_getdata_count >= 1, timeout=1)
|
||||
self.restart_node(0) # reset mocktime
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
|
|||
return node.get_wallet_rpc(wallet_name)
|
||||
|
||||
def run_test(self):
|
||||
node0, node1, node2 = self.nodes
|
||||
node0, node1, _node2 = self.nodes
|
||||
self.wallet = MiniWallet(test_node=node0)
|
||||
|
||||
if self.is_wallet_compiled():
|
||||
|
@ -122,7 +122,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
|
|||
assert_raises_rpc_error(-4, "Unsupported multisig script size for legacy wallet. Upgrade to descriptors to overcome this limitation for p2sh-segwit or bech32 scripts", wallet_multi.addmultisigaddress, 16, pubkeys, '', 'bech32')
|
||||
|
||||
def do_multisig(self, nkeys, nsigs, output_type, wallet_multi):
|
||||
node0, node1, node2 = self.nodes
|
||||
node0, _node1, node2 = self.nodes
|
||||
pub_keys = self.pub[0: nkeys]
|
||||
priv_keys = self.priv[0: nkeys]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2022 The Bitcoin Core developers
|
||||
# Copyright (c) 2015-present The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Utilities for manipulating blocks and transactions."""
|
||||
|
@ -74,7 +74,7 @@ def create_block(hashprev=None, coinbase=None, ntime=None, *, version=None, tmpl
|
|||
block.nVersion = version or tmpl.get('version') or VERSIONBITS_LAST_OLD_BLOCK_VERSION
|
||||
block.nTime = ntime or tmpl.get('curtime') or int(time.time() + 600)
|
||||
block.hashPrevBlock = hashprev or int(tmpl['previousblockhash'], 0x10)
|
||||
if tmpl and not tmpl.get('bits') is None:
|
||||
if tmpl and tmpl.get('bits') is not None:
|
||||
block.nBits = struct.unpack('>I', bytes.fromhex(tmpl['bits']))[0]
|
||||
else:
|
||||
block.nBits = 0x207fffff # difficulty retargeting is disabled in REGTEST chainparams
|
||||
|
|
|
@ -231,7 +231,7 @@ class UpgradeWalletTest(BitcoinTestFramework):
|
|||
assert b'\x07hdchain' in new_kvs
|
||||
hd_chain = new_kvs[b'\x07hdchain']
|
||||
assert_equal(28, len(hd_chain))
|
||||
hd_chain_version, external_counter, seed_id = struct.unpack('<iI20s', hd_chain)
|
||||
hd_chain_version, _external_counter, seed_id = struct.unpack('<iI20s', hd_chain)
|
||||
assert_equal(1, hd_chain_version)
|
||||
seed_id = bytearray(seed_id)
|
||||
seed_id.reverse()
|
||||
|
@ -258,7 +258,7 @@ class UpgradeWalletTest(BitcoinTestFramework):
|
|||
new_kvs = dump_bdb_kv(node_master_wallet)
|
||||
hd_chain = new_kvs[b'\x07hdchain']
|
||||
assert_equal(32, len(hd_chain))
|
||||
hd_chain_version, external_counter, seed_id, internal_counter = struct.unpack('<iI20sI', hd_chain)
|
||||
hd_chain_version, _external_counter, seed_id, internal_counter = struct.unpack('<iI20sI', hd_chain)
|
||||
assert_equal(2, hd_chain_version)
|
||||
assert_equal(0, internal_counter)
|
||||
seed_id = bytearray(seed_id)
|
||||
|
@ -284,7 +284,7 @@ class UpgradeWalletTest(BitcoinTestFramework):
|
|||
new_kvs = dump_bdb_kv(node_master_wallet)
|
||||
hd_chain = new_kvs[b'\x07hdchain']
|
||||
assert_equal(32, len(hd_chain))
|
||||
hd_chain_version, external_counter, seed_id, internal_counter = struct.unpack('<iI20sI', hd_chain)
|
||||
hd_chain_version, _external_counter, seed_id, internal_counter = struct.unpack('<iI20sI', hd_chain)
|
||||
assert_equal(2, hd_chain_version)
|
||||
assert_equal(2, internal_counter)
|
||||
# The next addresses are HD and should be on different HD chains (the one remaining key in each pool should have been flushed)
|
||||
|
@ -301,8 +301,8 @@ class UpgradeWalletTest(BitcoinTestFramework):
|
|||
new_kvs = dump_bdb_kv(node_master_wallet)
|
||||
for k, old_v in old_kvs.items():
|
||||
if k.startswith(b'\x07keymeta'):
|
||||
new_ver, new_create_time, new_kp_str, new_seed_id, new_fpr, new_path_len, new_path, new_has_key_orig = deser_keymeta(BytesIO(new_kvs[k]))
|
||||
old_ver, old_create_time, old_kp_str, old_seed_id, old_fpr, old_path_len, old_path, old_has_key_orig = deser_keymeta(BytesIO(old_v))
|
||||
new_ver, new_create_time, new_kp_str, new_seed_id, _new_fpr, new_path_len, new_path, new_has_key_orig = deser_keymeta(BytesIO(new_kvs[k]))
|
||||
old_ver, old_create_time, old_kp_str, old_seed_id, _old_fpr, old_path_len, old_path, old_has_key_orig = deser_keymeta(BytesIO(old_v))
|
||||
assert_equal(10, old_ver)
|
||||
if old_kp_str == b"": # imported things that don't have keymeta (i.e. imported coinbase privkeys) won't be upgraded
|
||||
assert_equal(new_kvs[k], old_v)
|
||||
|
|
|
@ -45,13 +45,13 @@ or `--help`:
|
|||
|
||||
| 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) | [mypy](https://github.com/python/mypy)
|
||||
| [`lint-python.py`](/test/lint/lint-python.py) | [pyzmq](https://github.com/zeromq/pyzmq)
|
||||
| [`lint-python-dead-code.py`](/test/lint/lint-python-dead-code.py) | [vulture](https://github.com/jendrikseipp/vulture)
|
||||
| [`lint-shell.py`](/test/lint/lint-shell.py) | [ShellCheck](https://github.com/koalaman/shellcheck)
|
||||
| [`lint-spelling.py`](/test/lint/lint-spelling.py) | [codespell](https://github.com/codespell-project/codespell)
|
||||
| `py_lint` | [ruff](https://github.com/astral-sh/ruff)
|
||||
| markdown link check | [mlc](https://github.com/becheran/mlc)
|
||||
|
||||
In use versions and install instructions are available in the [CI setup](../../ci/lint/04_install.sh).
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
# 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
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from importlib.metadata import metadata, PackageNotFoundError
|
||||
|
||||
|
@ -19,89 +18,12 @@ from importlib.metadata import metadata, PackageNotFoundError
|
|||
cache_dir = Path(__file__).parent.parent / ".mypy_cache"
|
||||
os.environ["MYPY_CACHE_DIR"] = str(cache_dir)
|
||||
|
||||
DEPS = ['flake8', 'lief', 'mypy', 'pyzmq']
|
||||
|
||||
# All .py files, except those in src/ (to exclude subtrees there)
|
||||
FLAKE_FILES_ARGS = ['git', 'ls-files', '*.py', ':!:src/*.py']
|
||||
DEPS = ['lief', 'mypy', 'pyzmq']
|
||||
|
||||
# Only .py files in test/functional and contrib/devtools have type annotations
|
||||
# enforced.
|
||||
MYPY_FILES_ARGS = ['git', 'ls-files', 'test/functional/*.py', 'contrib/devtools/*.py']
|
||||
|
||||
ENABLED = (
|
||||
'E101,' # indentation contains mixed spaces and tabs
|
||||
'E112,' # expected an indented block
|
||||
'E113,' # unexpected indentation
|
||||
'E115,' # expected an indented block (comment)
|
||||
'E116,' # unexpected indentation (comment)
|
||||
'E125,' # continuation line with same indent as next logical line
|
||||
'E129,' # visually indented line with same indent as next logical line
|
||||
'E131,' # continuation line unaligned for hanging indent
|
||||
'E133,' # closing bracket is missing indentation
|
||||
'E223,' # tab before operator
|
||||
'E224,' # tab after operator
|
||||
'E242,' # tab after ','
|
||||
'E266,' # too many leading '#' for block comment
|
||||
'E271,' # multiple spaces after keyword
|
||||
'E272,' # multiple spaces before keyword
|
||||
'E273,' # tab after keyword
|
||||
'E274,' # tab before keyword
|
||||
'E275,' # missing whitespace after keyword
|
||||
'E304,' # blank lines found after function decorator
|
||||
'E306,' # expected 1 blank line before a nested definition
|
||||
'E401,' # multiple imports on one line
|
||||
'E402,' # module level import not at top of file
|
||||
'E502,' # the backslash is redundant between brackets
|
||||
'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"
|
||||
'E901,' # SyntaxError: invalid syntax
|
||||
'E902,' # TokenError: EOF in multi-line string
|
||||
'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
|
||||
'F622,' # two or more starred expressions in an assignment (a, *b, *c = d)
|
||||
'F631,' # assertion test is a tuple, which are always True
|
||||
'F632,' # use ==/!= to compare str, bytes, and int literals
|
||||
'F701,' # a break statement outside of a while or for loop
|
||||
'F702,' # a continue statement outside of a while or for loop
|
||||
'F703,' # a continue statement in a finally block in a loop
|
||||
'F704,' # a yield or yield from statement outside of a function
|
||||
'F705,' # a return statement with arguments inside a generator
|
||||
'F706,' # a return statement outside of a function/method
|
||||
'F707,' # an except: block as not the last exception handler
|
||||
'F811,' # redefinition of unused name from line N
|
||||
'F812,' # list comprehension redefines 'foo' from line N
|
||||
'F821,' # undefined name 'Foo'
|
||||
'F822,' # undefined name name in __all__
|
||||
'F823,' # local variable name … referenced before assignment
|
||||
'F831,' # duplicate argument name in function definition
|
||||
'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
|
||||
'W601,' # .has_key() is deprecated, use "in"
|
||||
'W602,' # deprecated form of raising exception
|
||||
'W603,' # "<>" is deprecated, use "!="
|
||||
'W604,' # backticks are deprecated, use "repr()"
|
||||
'W605,' # invalid escape sequence "x"
|
||||
'W606,' # 'async' and 'await' are reserved keywords starting with Python 3.7
|
||||
)
|
||||
|
||||
|
||||
def check_dependencies():
|
||||
for dep in DEPS:
|
||||
|
@ -115,20 +37,6 @@ def check_dependencies():
|
|||
def main():
|
||||
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_args = ['mypy', '--show-error-codes'] + mypy_files
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ fn get_linter_list() -> Vec<&'static Linter> {
|
|||
lint_fn: lint_markdown
|
||||
},
|
||||
&Linter {
|
||||
description: "Check the default arguments in python",
|
||||
name: "py_mut_arg_default",
|
||||
lint_fn: lint_py_mut_arg_default,
|
||||
description: "Lint Python code",
|
||||
name: "py_lint",
|
||||
lint_fn: lint_py_lint,
|
||||
},
|
||||
&Linter {
|
||||
description: "Check that std::filesystem is not used directly",
|
||||
|
@ -185,12 +185,50 @@ fn lint_subtree() -> LintResult {
|
|||
}
|
||||
}
|
||||
|
||||
fn lint_py_mut_arg_default() -> LintResult {
|
||||
fn lint_py_lint() -> LintResult {
|
||||
let bin_name = "ruff";
|
||||
let checks = ["B006", "B008"]
|
||||
.iter()
|
||||
.map(|c| format!("--select={}", c))
|
||||
.collect::<Vec<_>>();
|
||||
let checks = format!(
|
||||
"--select={}",
|
||||
[
|
||||
"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(
|
||||
git()
|
||||
.args(["ls-files", "--", "*.py"])
|
||||
|
@ -198,7 +236,7 @@ fn lint_py_mut_arg_default() -> LintResult {
|
|||
)?;
|
||||
|
||||
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() {
|
||||
Ok(status) if status.success() => Ok(()),
|
||||
|
|
Loading…
Reference in a new issue