From d516cf83ed2da86dfefb395cd46f8a894907b88e Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Wed, 25 Oct 2023 00:55:17 +0200 Subject: [PATCH] test: use built-in collection types for type hints (Python 3.9 / PEP 585) Since Python 3.9, type hinting has become a little less awkward, as for collection types one doesn't need to import the corresponding capitalized types (`Dict`, `List`, `Set`, `Tuple`, ...) anymore, but can use the built-in types directly. [1] [2] This commit applies the replacement for all Python scripts (i.e. in the contrib and test folders) for the basic types: - typing.Dict -> dict - typing.List -> list - typing.Set -> set - typing.Tuple -> tuple [1] https://docs.python.org/3.9/whatsnew/3.9.html#type-hinting-generics-in-standard-collections [2] https://peps.python.org/pep-0585/#implementation for a list of type --- contrib/devtools/circular-dependencies.py | 5 +- contrib/devtools/security-check.py | 3 +- contrib/devtools/symbol-check.py | 7 +- contrib/devtools/test-security-check.py | 3 +- contrib/devtools/test-symbol-check.py | 7 +- contrib/devtools/utils.py | 3 +- contrib/macdeploy/macdeployqtplus | 6 +- .../message-capture/message-capture-parser.py | 6 +- contrib/seeds/asmap.py | 80 +++++++++---------- contrib/seeds/makeseeds.py | 16 ++-- test/functional/interface_rest.py | 2 +- test/functional/test_framework/script.py | 5 +- .../test_framework/test_framework.py | 3 +- test/functional/test_framework/util.py | 4 +- test/functional/test_framework/wallet.py | 3 +- test/functional/wallet_fast_rescan.py | 4 +- test/lint/lint-files.py | 4 +- test/lint/lint-include-guards.py | 3 +- 18 files changed, 76 insertions(+), 88 deletions(-) diff --git a/contrib/devtools/circular-dependencies.py b/contrib/devtools/circular-dependencies.py index b1d9f2b7db2..b742a8cea67 100755 --- a/contrib/devtools/circular-dependencies.py +++ b/contrib/devtools/circular-dependencies.py @@ -5,7 +5,6 @@ import sys import re -from typing import Dict, List, Set MAPPING = { 'core_read.cpp': 'core_io.cpp', @@ -33,7 +32,7 @@ def module_name(path): return None files = dict() -deps: Dict[str, Set[str]] = dict() +deps: dict[str, set[str]] = dict() RE = re.compile("^#include <(.*)>") @@ -65,7 +64,7 @@ while True: shortest_cycle = None for module in sorted(deps.keys()): # Build the transitive closure of dependencies of module - closure: Dict[str, List[str]] = dict() + closure: dict[str, list[str]] = dict() for dep in deps[module]: closure[dep] = [] while True: diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index f90fa5785f0..590c2ed87d2 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -8,7 +8,6 @@ Exit status will be 0 if successful, and the program will be silent. Otherwise the exit status will be 1 and it will log which executables failed which checks. ''' import sys -from typing import List import lief @@ -255,7 +254,7 @@ if __name__ == '__main__': retval = 1 continue - failed: List[str] = [] + failed: list[str] = [] for (name, func) in CHECKS[etype][arch]: if not func(binary): failed.append(name) diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index a3d00bec957..e3e8e398c22 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -11,7 +11,6 @@ Example usage: find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py ''' import sys -from typing import List, Dict import lief @@ -53,7 +52,7 @@ IGNORE_EXPORTS = { # Expected linker-loader names can be found here: # https://sourceware.org/glibc/wiki/ABIList?action=recall&rev=16 -ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = { +ELF_INTERPRETER_NAMES: dict[lief.ELF.ARCH, dict[lief.ENDIANNESS, str]] = { lief.ELF.ARCH.x86_64: { lief.ENDIANNESS.LITTLE: "/lib64/ld-linux-x86-64.so.2", }, @@ -72,7 +71,7 @@ ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = { }, } -ELF_ABIS: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, List[int]]] = { +ELF_ABIS: dict[lief.ELF.ARCH, dict[lief.ENDIANNESS, list[int]]] = { lief.ELF.ARCH.x86_64: { lief.ENDIANNESS.LITTLE: [3,2,0], }, @@ -302,7 +301,7 @@ if __name__ == '__main__': retval = 1 continue - failed: List[str] = [] + failed: list[str] = [] for (name, func) in CHECKS[etype]: if not func(binary): failed.append(name) diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index 802bf9fd303..bb900ec3d12 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -8,7 +8,6 @@ Test script for security-check.py import lief import os import subprocess -from typing import List import unittest from utils import determine_wellknown_cmd @@ -34,7 +33,7 @@ def call_security_check(cc: str, source: str, executable: str, options) -> tuple # # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for # reference. - env_flags: List[str] = [] + env_flags: list[str] = [] for var in ['CFLAGS', 'CPPFLAGS', 'LDFLAGS']: env_flags += filter(None, os.environ.get(var, '').split(' ')) diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py index fe8a99739f1..0140decb25f 100755 --- a/contrib/devtools/test-symbol-check.py +++ b/contrib/devtools/test-symbol-check.py @@ -7,18 +7,17 @@ Test script for symbol-check.py ''' import os import subprocess -from typing import List import unittest from utils import determine_wellknown_cmd -def call_symbol_check(cc: List[str], source, executable, options): +def call_symbol_check(cc: list[str], source, executable, options): # This should behave the same as AC_TRY_LINK, so arrange well-known flags # in the same order as autoconf would. # # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for # reference. - env_flags: List[str] = [] + env_flags: list[str] = [] for var in ['CFLAGS', 'CPPFLAGS', 'LDFLAGS']: env_flags += filter(None, os.environ.get(var, '').split(' ')) @@ -28,7 +27,7 @@ def call_symbol_check(cc: List[str], source, executable, options): os.remove(executable) return (p.returncode, p.stdout.rstrip()) -def get_machine(cc: List[str]): +def get_machine(cc: list[str]): p = subprocess.run([*cc,'-dumpmachine'], stdout=subprocess.PIPE, text=True) return p.stdout.rstrip() diff --git a/contrib/devtools/utils.py b/contrib/devtools/utils.py index 68ad1c3aba1..8b4c67c6c0c 100755 --- a/contrib/devtools/utils.py +++ b/contrib/devtools/utils.py @@ -8,10 +8,9 @@ Common utility functions import shutil import sys import os -from typing import List -def determine_wellknown_cmd(envvar, progname) -> List[str]: +def determine_wellknown_cmd(envvar, progname) -> list[str]: maybe_env = os.getenv(envvar) maybe_which = shutil.which(progname) if maybe_env: diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index fa9b8683491..4b1d72650d6 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -20,7 +20,7 @@ import sys, re, os, platform, shutil, stat, subprocess, os.path from argparse import ArgumentParser from pathlib import Path from subprocess import PIPE, run -from typing import List, Optional +from typing import Optional # This is ported from the original macdeployqt with modifications @@ -181,7 +181,7 @@ class DeploymentInfo(object): return True return False -def getFrameworks(binaryPath: str, verbose: int) -> List[FrameworkInfo]: +def getFrameworks(binaryPath: str, verbose: int) -> list[FrameworkInfo]: if verbose: print(f"Inspecting with otool: {binaryPath}") otoolbin=os.getenv("OTOOL", "otool") @@ -285,7 +285,7 @@ def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional return toPath -def deployFrameworks(frameworks: List[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo: +def deployFrameworks(frameworks: list[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo: if deploymentInfo is None: deploymentInfo = DeploymentInfo() diff --git a/contrib/message-capture/message-capture-parser.py b/contrib/message-capture/message-capture-parser.py index d6ddc1c149a..0f409717d4c 100755 --- a/contrib/message-capture/message-capture-parser.py +++ b/contrib/message-capture/message-capture-parser.py @@ -11,7 +11,7 @@ import sys from io import BytesIO import json from pathlib import Path -from typing import Any, List, Optional +from typing import Any, Optional sys.path.append(os.path.join(os.path.dirname(__file__), '../../test/functional')) @@ -92,7 +92,7 @@ def to_jsonable(obj: Any) -> Any: return obj -def process_file(path: str, messages: List[Any], recv: bool, progress_bar: Optional[ProgressBar]) -> None: +def process_file(path: str, messages: list[Any], recv: bool, progress_bar: Optional[ProgressBar]) -> None: with open(path, 'rb') as f_in: if progress_bar: bytes_read = 0 @@ -188,7 +188,7 @@ def main(): output = Path.cwd() / Path(args.output) if args.output else False use_progress_bar = (not args.no_progress_bar) and sys.stdout.isatty() - messages = [] # type: List[Any] + messages = [] # type: list[Any] if use_progress_bar: total_size = sum(capture.stat().st_size for capture in capturepaths) progress_bar = ProgressBar(total_size) diff --git a/contrib/seeds/asmap.py b/contrib/seeds/asmap.py index e28e5cf532e..84e1811ede8 100644 --- a/contrib/seeds/asmap.py +++ b/contrib/seeds/asmap.py @@ -12,9 +12,9 @@ import random import unittest from enum import Enum from functools import total_ordering -from typing import Callable, Dict, Iterable, List, Optional, Tuple, Union, overload +from typing import Callable, Iterable, Optional, Union, overload -def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> List[bool]: +def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> list[bool]: """ Convert an IPv4 or IPv6 network to a prefix represented as a list of bits. @@ -32,7 +32,7 @@ def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> Li assert (netrange & ((1 << (128 - num_bits)) - 1)) == 0 return [((netrange >> (127 - i)) & 1) != 0 for i in range(num_bits)] -def prefix_to_net(prefix: List[bool]) -> Union[ipaddress.IPv4Network,ipaddress.IPv6Network]: +def prefix_to_net(prefix: list[bool]) -> Union[ipaddress.IPv4Network,ipaddress.IPv6Network]: """The reverse operation of net_to_prefix.""" # Convert to number netrange = sum(b << (127 - i) for i, b in enumerate(prefix)) @@ -47,10 +47,10 @@ def prefix_to_net(prefix: List[bool]) -> Union[ipaddress.IPv4Network,ipaddress.I return ipaddress.IPv6Network((netrange, num_bits), True) # Shortcut for (prefix, ASN) entries. -ASNEntry = Tuple[List[bool], int] +ASNEntry = tuple[list[bool], int] # Shortcut for (prefix, old ASN, new ASN) entries. -ASNDiff = Tuple[List[bool], int, int] +ASNDiff = tuple[list[bool], int, int] class _VarLenCoder: """ @@ -75,7 +75,7 @@ class _VarLenCoder: other classes start one past the last element of the class before it. """ - def __init__(self, minval: int, clsbits: List[int]): + def __init__(self, minval: int, clsbits: list[int]): """Construct a new _VarLenCoder.""" self._minval = minval self._clsbits = clsbits @@ -85,7 +85,7 @@ class _VarLenCoder: """Check whether value val is in the range this coder supports.""" return self._minval <= val <= self._maxval - def encode(self, val: int, ret: List[int]) -> None: + def encode(self, val: int, ret: list[int]) -> None: """Append encoding of val onto integer list ret.""" assert self._minval <= val <= self._maxval @@ -120,7 +120,7 @@ class _VarLenCoder: break return ret + bits - def decode(self, stream, bitpos) -> Tuple[int,int]: + def decode(self, stream, bitpos) -> tuple[int,int]: """Decode a number starting at bitpos in stream, returning value and new bitpos.""" val = self._minval bits = 0 @@ -281,11 +281,11 @@ class ASMap: - mappings, represented by new trie nodes. """ - def update(self, prefix: List[bool], asn: int) -> None: + def update(self, prefix: list[bool], asn: int) -> None: """Update this ASMap object to map prefix to the specified asn.""" assert asn == 0 or _CODER_ASN.can_encode(asn) - def recurse(node: List, offset: int) -> None: + def recurse(node: list, offset: int) -> None: if offset == len(prefix): # Reached the end of prefix; overwrite this node. node.clear() @@ -306,7 +306,7 @@ class ASMap: node.append(oldasn) recurse(self._trie, 0) - def update_multi(self, entries: List[Tuple[List[bool], int]]) -> None: + def update_multi(self, entries: list[tuple[list[bool], int]]) -> None: """Apply multiple update operations, where longer prefixes take precedence.""" entries.sort(key=lambda entry: len(entry[0])) for prefix, asn in entries: @@ -314,7 +314,7 @@ class ASMap: def _set_trie(self, trie) -> None: """Set trie directly. Internal use only.""" - def recurse(node: List) -> None: + def recurse(node: list) -> None: if len(node) < 2: return recurse(node[0]) @@ -342,7 +342,7 @@ class ASMap: for prefix, asn in sorted(entries, key=entry_key): self.update(prefix, asn) - def lookup(self, prefix: List[bool]) -> Optional[int]: + def lookup(self, prefix: list[bool]) -> Optional[int]: """Look up a prefix. Returns ASN, or 0 if unassigned, or None if indeterminate.""" node = self._trie for bit in prefix: @@ -353,11 +353,11 @@ class ASMap: return node[0] return None - def _to_entries_flat(self, fill: bool = False) -> List[ASNEntry]: + def _to_entries_flat(self, fill: bool = False) -> list[ASNEntry]: """Convert an ASMap object to a list of non-overlapping (prefix, asn) objects.""" - prefix : List[bool] = [] + prefix : list[bool] = [] - def recurse(node: List) -> List[ASNEntry]: + def recurse(node: list) -> list[ASNEntry]: ret = [] if len(node) == 1: if node[0] > 0: @@ -375,24 +375,24 @@ class ASMap: return ret return recurse(self._trie) - def _to_entries_minimal(self, fill: bool = False) -> List[ASNEntry]: + def _to_entries_minimal(self, fill: bool = False) -> list[ASNEntry]: """Convert a trie to a minimal list of ASNEntry objects, exploiting overlap.""" - prefix : List[bool] = [] + prefix : list[bool] = [] - def recurse(node: List) -> (Tuple[Dict[Optional[int], List[ASNEntry]], bool]): + def recurse(node: list) -> (tuple[dict[Optional[int], list[ASNEntry]], bool]): if len(node) == 1 and node[0] == 0: return {None if fill else 0: []}, True if len(node) == 1: return {node[0]: [], None: [(list(prefix), node[0])]}, False - ret: Dict[Optional[int], List[ASNEntry]] = {} + ret: dict[Optional[int], list[ASNEntry]] = {} prefix.append(False) left, lhole = recurse(node[0]) prefix[-1] = True right, rhole = recurse(node[1]) prefix.pop() hole = not fill and (lhole or rhole) - def candidate(ctx: Optional[int], res0: Optional[List[ASNEntry]], - res1: Optional[List[ASNEntry]]): + def candidate(ctx: Optional[int], res0: Optional[list[ASNEntry]], + res1: Optional[list[ASNEntry]]): if res0 is not None and res1 is not None: if ctx not in ret or len(res0) + len(res1) < len(ret[ctx]): ret[ctx] = res0 + res1 @@ -417,7 +417,7 @@ class ASMap: """Convert this ASMap object to a string containing Python code constructing it.""" return f"ASMap({self._trie})" - def to_entries(self, overlapping: bool = True, fill: bool = False) -> List[ASNEntry]: + def to_entries(self, overlapping: bool = True, fill: bool = False) -> list[ASNEntry]: """ Convert the mappings in this ASMap object to a list of ASNEntry objects. @@ -448,7 +448,7 @@ class ASMap: assert max_asn >= 1 or unassigned_prob == 1 assert _CODER_ASN.can_encode(max_asn) assert 0.0 <= unassigned_prob <= 1.0 - trie: List = [] + trie: list = [] leaves = [trie] ret = ASMap() for i in range(1, num_leaves): @@ -472,12 +472,12 @@ class ASMap: def _to_binnode(self, fill: bool = False) -> _BinNode: """Convert a trie to a _BinNode object.""" - def recurse(node: List) -> Tuple[Dict[Optional[int], _BinNode], bool]: + def recurse(node: list) -> tuple[dict[Optional[int], _BinNode], bool]: if len(node) == 1 and node[0] == 0: return {(None if fill else 0): _BinNode.make_end()}, True if len(node) == 1: return {None: _BinNode.make_leaf(node[0]), node[0]: _BinNode.make_end()}, False - ret: Dict[Optional[int], _BinNode] = {} + ret: dict[Optional[int], _BinNode] = {} left, lhole = recurse(node[0]) right, rhole = recurse(node[1]) hole = (lhole or rhole) and not fill @@ -507,7 +507,7 @@ class ASMap: @staticmethod def _from_binnode(binnode: _BinNode) -> "ASMap": """Construct an ASMap object from a _BinNode. Internal use only.""" - def recurse(node: _BinNode, default: int) -> List: + def recurse(node: _BinNode, default: int) -> list: if node.ins == _Instruction.RETURN: return [node.arg1] if node.ins == _Instruction.JUMP: @@ -542,7 +542,7 @@ class ASMap: Returns: A bytes object with the encoding of this ASMap object. """ - bits: List[int] = [] + bits: list[int] = [] def recurse(node: _BinNode) -> None: _CODER_INS.encode(node.ins.value, bits) @@ -582,11 +582,11 @@ class ASMap: def from_binary(bindata: bytes) -> Optional["ASMap"]: """Decode an ASMap object from the provided binary encoding.""" - bits: List[int] = [] + bits: list[int] = [] for byte in bindata: bits.extend((byte >> i) & 1 for i in range(8)) - def recurse(bitpos: int) -> Tuple[_BinNode, int]: + def recurse(bitpos: int) -> tuple[_BinNode, int]: insval, bitpos = _CODER_INS.decode(bits, bitpos) ins = _Instruction(insval) if ins == _Instruction.RETURN: @@ -632,7 +632,7 @@ class ASMap: def extends(self, req: "ASMap") -> bool: """Determine whether this matches req for all subranges where req is assigned.""" - def recurse(actual: List, require: List) -> bool: + def recurse(actual: list, require: list) -> bool: if len(require) == 1 and require[0] == 0: return True if len(require) == 1: @@ -646,20 +646,20 @@ class ASMap: #pylint: disable=protected-access return recurse(self._trie, req._trie) - def diff(self, other: "ASMap") -> List[ASNDiff]: + def diff(self, other: "ASMap") -> list[ASNDiff]: """Compute the diff from self to other.""" - prefix: List[bool] = [] - ret: List[ASNDiff] = [] + prefix: list[bool] = [] + ret: list[ASNDiff] = [] - def recurse(old_node: List, new_node: List): + def recurse(old_node: list, new_node: list): if len(old_node) == 1 and len(new_node) == 1: if old_node[0] != new_node[0]: ret.append((list(prefix), old_node[0], new_node[0])) else: - old_left: List = old_node if len(old_node) == 1 else old_node[0] - old_right: List = old_node if len(old_node) == 1 else old_node[1] - new_left: List = new_node if len(new_node) == 1 else new_node[0] - new_right: List = new_node if len(new_node) == 1 else new_node[1] + old_left: list = old_node if len(old_node) == 1 else old_node[0] + old_right: list = old_node if len(old_node) == 1 else old_node[1] + new_left: list = new_node if len(new_node) == 1 else new_node[0] + new_right: list = new_node if len(new_node) == 1 else new_node[1] prefix.append(False) recurse(old_left, new_left) prefix[-1] = True @@ -760,7 +760,7 @@ class TestASMap(unittest.TestCase): # It starts off being equal to asmap. patched = copy.copy(asmap) # Keep a list of patches performed. - patches: List[ASNEntry] = [] + patches: list[ASNEntry] = [] # Initially there cannot be any difference. self.assertEqual(asmap.diff(patched), []) # Make 5 patches, each building on top of the previous ones. diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index af408c2df53..f03c2ab5e80 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -11,7 +11,7 @@ import collections import ipaddress import re import sys -from typing import List, Dict, Union +from typing import Union from asmap import ASMap, net_to_prefix @@ -117,14 +117,14 @@ def parseline(line: str) -> Union[dict, None]: 'sortkey': sortkey, } -def dedup(ips: List[Dict]) -> List[Dict]: +def dedup(ips: list[dict]) -> list[dict]: """ Remove duplicates from `ips` where multiple ips share address and port. """ d = {} for ip in ips: d[ip['ip'],ip['port']] = ip return list(d.values()) -def filtermultiport(ips: List[Dict]) -> List[Dict]: +def filtermultiport(ips: list[dict]) -> list[dict]: """ Filter out hosts with more nodes per IP""" hist = collections.defaultdict(list) for ip in ips: @@ -132,7 +132,7 @@ def filtermultiport(ips: List[Dict]) -> List[Dict]: return [value[0] for (key,value) in list(hist.items()) if len(value)==1] # Based on Greg Maxwell's seed_filter.py -def filterbyasn(asmap: ASMap, ips: List[Dict], max_per_asn: Dict, max_per_net: int) -> List[Dict]: +def filterbyasn(asmap: ASMap, ips: list[dict], max_per_asn: dict, max_per_net: int) -> list[dict]: """ Prunes `ips` by (a) trimming ips to have at most `max_per_net` ips from each net (e.g. ipv4, ipv6); and (b) trimming ips to have at most `max_per_asn` ips from each asn in each net. @@ -143,8 +143,8 @@ def filterbyasn(asmap: ASMap, ips: List[Dict], max_per_asn: Dict, max_per_net: i # Filter IPv46 by ASN, and limit to max_per_net per network result = [] - net_count: Dict[str, int] = collections.defaultdict(int) - asn_count: Dict[int, int] = collections.defaultdict(int) + net_count: dict[str, int] = collections.defaultdict(int) + asn_count: dict[int, int] = collections.defaultdict(int) for i, ip in enumerate(ips_ipv46): if net_count[ip['net']] == max_per_net: @@ -165,9 +165,9 @@ def filterbyasn(asmap: ASMap, ips: List[Dict], max_per_asn: Dict, max_per_net: i result.extend(ips_onion[0:max_per_net]) return result -def ip_stats(ips: List[Dict]) -> str: +def ip_stats(ips: list[dict]) -> str: """ Format and return pretty string from `ips`. """ - hist: Dict[str, int] = collections.defaultdict(int) + hist: dict[str, int] = collections.defaultdict(int) for ip in ips: if ip is not None: hist[ip['net']] += 1 diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py index c0679c5ba9c..b81eae25064 100755 --- a/test/functional/interface_rest.py +++ b/test/functional/interface_rest.py @@ -65,7 +65,7 @@ class RESTTest (BitcoinTestFramework): body: str = '', status: int = 200, ret_type: RetType = RetType.JSON, - query_params: Optional[typing.Dict[str, typing.Any]] = None, + query_params: Optional[dict[str, typing.Any]] = None, ) -> typing.Union[http.client.HTTPResponse, bytes, str, None]: rest_uri = '/rest' + uri if req_type in ReqType: diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py index 17a954cb22c..b3d55158ece 100644 --- a/test/functional/test_framework/script.py +++ b/test/functional/test_framework/script.py @@ -10,7 +10,6 @@ This file is modified from python-bitcoinlib. from collections import namedtuple import struct import unittest -from typing import List, Dict from .key import TaggedHash, tweak_add_pubkey, compute_xonly_pubkey @@ -110,8 +109,8 @@ class CScriptOp(int): _opcode_instances.append(super().__new__(cls, n)) return _opcode_instances[n] -OPCODE_NAMES: Dict[CScriptOp, str] = {} -_opcode_instances: List[CScriptOp] = [] +OPCODE_NAMES: dict[CScriptOp, str] = {} +_opcode_instances: list[CScriptOp] = [] # Populate opcode instance table for n in range(0xff + 1): diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 4e6d245b5fe..e182eb0e99f 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -19,7 +19,6 @@ import sys import tempfile import time -from typing import List from .address import create_deterministic_address_bcrt1_p2tr_op_true from .authproxy import JSONRPCException from . import coverage @@ -96,7 +95,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): """Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method""" self.chain: str = 'regtest' self.setup_clean_chain: bool = False - self.nodes: List[TestNode] = [] + self.nodes: list[TestNode] = [] self.extra_args = None self.network_thread = None self.rpc_timeout = 60 # Wait for up to 60 seconds for the RPC server to respond diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 96d70b73801..8ee1ef70089 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -20,7 +20,7 @@ import time from . import coverage from .authproxy import AuthServiceProxy, JSONRPCException -from typing import Callable, Optional, Tuple +from typing import Callable, Optional logger = logging.getLogger("TestFramework.utils") @@ -416,7 +416,7 @@ def get_datadir_path(dirname, n): return pathlib.Path(dirname) / f"node{n}" -def get_temp_default_datadir(temp_dir: pathlib.Path) -> Tuple[dict, pathlib.Path]: +def get_temp_default_datadir(temp_dir: pathlib.Path) -> tuple[dict, pathlib.Path]: """Return os-specific environment variables that can be set to make the GetDefaultDataDir() function return a datadir path under the provided temp_dir, as well as the complete path it would return.""" diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py index 035a482f4cb..53c8e1b0cc4 100644 --- a/test/functional/test_framework/wallet.py +++ b/test/functional/test_framework/wallet.py @@ -9,7 +9,6 @@ from decimal import Decimal from enum import Enum from typing import ( Any, - List, Optional, ) from test_framework.address import ( @@ -284,7 +283,7 @@ class MiniWallet: def create_self_transfer_multi( self, *, - utxos_to_spend: Optional[List[dict]] = None, + utxos_to_spend: Optional[list[dict]] = None, num_outputs=1, amount_per_output=0, locktime=0, diff --git a/test/functional/wallet_fast_rescan.py b/test/functional/wallet_fast_rescan.py index 2f9c924e71a..1315bccafdc 100755 --- a/test/functional/wallet_fast_rescan.py +++ b/test/functional/wallet_fast_rescan.py @@ -4,8 +4,6 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test that fast rescan using block filters for descriptor wallets detects top-ups correctly and finds the same transactions than the slow variant.""" -from typing import List - from test_framework.address import address_to_scriptpubkey from test_framework.descriptors import descsum_create from test_framework.test_framework import BitcoinTestFramework @@ -32,7 +30,7 @@ class WalletFastRescanTest(BitcoinTestFramework): self.skip_if_no_wallet() self.skip_if_no_sqlite() - def get_wallet_txids(self, node: TestNode, wallet_name: str) -> List[str]: + def get_wallet_txids(self, node: TestNode, wallet_name: str) -> list[str]: w = node.get_wallet_rpc(wallet_name) txs = w.listtransactions('*', 1000000) return [tx['txid'] for tx in txs] diff --git a/test/lint/lint-files.py b/test/lint/lint-files.py index f2b5db681b7..86fe727b065 100755 --- a/test/lint/lint-files.py +++ b/test/lint/lint-files.py @@ -11,7 +11,7 @@ import os import re import sys from subprocess import check_output -from typing import Dict, Optional, NoReturn +from typing import Optional, NoReturn CMD_TOP_LEVEL = ["git", "rev-parse", "--show-toplevel"] CMD_ALL_FILES = ["git", "ls-files", "-z", "--full-name", "--stage"] @@ -69,7 +69,7 @@ class FileMeta(object): return None -def get_git_file_metadata() -> Dict[str, FileMeta]: +def get_git_file_metadata() -> dict[str, FileMeta]: ''' Return a dictionary mapping the name of all files in the repository to git tree metadata. ''' diff --git a/test/lint/lint-include-guards.py b/test/lint/lint-include-guards.py index 48b918e9dab..291e528c1db 100755 --- a/test/lint/lint-include-guards.py +++ b/test/lint/lint-include-guards.py @@ -11,7 +11,6 @@ Check include guards. import re import sys from subprocess import check_output -from typing import List HEADER_ID_PREFIX = 'BITCOIN_' @@ -28,7 +27,7 @@ EXCLUDE_FILES_WITH_PREFIX = ['contrib/devtools/bitcoin-tidy', 'src/test/fuzz/FuzzedDataProvider.h'] -def _get_header_file_lst() -> List[str]: +def _get_header_file_lst() -> list[str]: """ Helper function to get a list of header filepaths to be checked for include guards. """