From beb49ab121d268b0f86c5bd9c6e191328fe91915 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Tue, 29 Mar 2022 13:51:08 +0200 Subject: [PATCH 1/2] don't use #noqa for imports --- docs/scripts/api-events.py | 1 - examples/addons/io-write-flow-file.py | 2 +- examples/contrib/har_dump.py | 2 +- examples/contrib/sslstrip.py | 2 +- mitmproxy/addons/eventstore.py | 2 +- mitmproxy/addons/stickycookie.py | 2 +- mitmproxy/contentviews/raw.py | 2 -- mitmproxy/flow.py | 2 +- mitmproxy/io/compat.py | 2 +- mitmproxy/net/encoding.py | 25 +++++++++---------- mitmproxy/tools/console/flowlist.py | 2 +- mitmproxy/tools/console/flowview.py | 6 ++--- .../tools/console/grideditor/__init__.py | 23 +++++++++++++++-- mitmproxy/tools/console/grideditor/base.py | 2 +- mitmproxy/tools/console/palettes.py | 2 +- mitmproxy/tools/console/statusbar.py | 2 +- 16 files changed, 47 insertions(+), 32 deletions(-) diff --git a/docs/scripts/api-events.py b/docs/scripts/api-events.py index eca751a79..4925610f6 100644 --- a/docs/scripts/api-events.py +++ b/docs/scripts/api-events.py @@ -5,7 +5,6 @@ import textwrap from pathlib import Path from typing import List, Type -import mitmproxy.addons.next_layer # noqa from mitmproxy import hooks, log, addonmanager from mitmproxy.proxy import server_hooks, layer from mitmproxy.proxy.layers import http, modes, tcp, tls, websocket diff --git a/examples/addons/io-write-flow-file.py b/examples/addons/io-write-flow-file.py index e885051d4..567acc6a6 100644 --- a/examples/addons/io-write-flow-file.py +++ b/examples/addons/io-write-flow-file.py @@ -10,7 +10,7 @@ to multiple files in parallel. import random import sys from mitmproxy import io, http -import typing # noqa +import typing class Writer: diff --git a/examples/contrib/har_dump.py b/examples/contrib/har_dump.py index 14ecad701..747a7a18a 100644 --- a/examples/contrib/har_dump.py +++ b/examples/contrib/har_dump.py @@ -13,7 +13,7 @@ import json import base64 import zlib import os -import typing # noqa +import typing from datetime import datetime from datetime import timezone diff --git a/examples/contrib/sslstrip.py b/examples/contrib/sslstrip.py index 16d9b59a4..7b053d440 100644 --- a/examples/contrib/sslstrip.py +++ b/examples/contrib/sslstrip.py @@ -4,7 +4,7 @@ https://moxie.org/software/sslstrip/ """ import re import urllib.parse -import typing # noqa +import typing from mitmproxy import http diff --git a/mitmproxy/addons/eventstore.py b/mitmproxy/addons/eventstore.py index ca20dcd1f..0cf5de70e 100644 --- a/mitmproxy/addons/eventstore.py +++ b/mitmproxy/addons/eventstore.py @@ -1,5 +1,5 @@ import collections -import typing # noqa +import typing import blinker diff --git a/mitmproxy/addons/stickycookie.py b/mitmproxy/addons/stickycookie.py index 3b67bb82c..3d0e12f03 100644 --- a/mitmproxy/addons/stickycookie.py +++ b/mitmproxy/addons/stickycookie.py @@ -1,6 +1,6 @@ import collections from http import cookiejar -from typing import List, Tuple, Dict, Optional # noqa +from typing import List, Tuple, Dict, Optional from mitmproxy import http, flowfilter, ctx, exceptions from mitmproxy.net.http import cookies diff --git a/mitmproxy/contentviews/raw.py b/mitmproxy/contentviews/raw.py index 248021403..a0b0884ec 100644 --- a/mitmproxy/contentviews/raw.py +++ b/mitmproxy/contentviews/raw.py @@ -1,5 +1,3 @@ -from typing import List # noqa - from mitmproxy.utils import strutils from . import base diff --git a/mitmproxy/flow.py b/mitmproxy/flow.py index 8767ba504..9a1976cbd 100644 --- a/mitmproxy/flow.py +++ b/mitmproxy/flow.py @@ -1,6 +1,6 @@ import asyncio import time -import typing # noqa +import typing import uuid from mitmproxy import connection diff --git a/mitmproxy/io/compat.py b/mitmproxy/io/compat.py index 368eb0d96..86f62a1ef 100644 --- a/mitmproxy/io/compat.py +++ b/mitmproxy/io/compat.py @@ -6,7 +6,7 @@ v3.0.0dev) and versioning. Every change or migration gets a new flow file version number, this prevents issues with developer builds and snapshots. """ import uuid -from typing import Any, Dict, Mapping, Union # noqa +from typing import Any, Dict, Mapping, Union from mitmproxy import version from mitmproxy.utils import strutils diff --git a/mitmproxy/net/encoding.py b/mitmproxy/net/encoding.py index 854931e60..f13c808d6 100644 --- a/mitmproxy/net/encoding.py +++ b/mitmproxy/net/encoding.py @@ -4,15 +4,14 @@ Utility functions for decoding response bodies. import codecs import collections -from io import BytesIO - import gzip import zlib +from io import BytesIO +from typing import Union, overload + import brotli import zstandard as zstd -from typing import Union, Optional, AnyStr, overload # noqa - # We have a shared single-element cache for encoding and decoding. # This is quite useful in practice, e.g. # flow.request.content = flow.request.content.replace(b"foo", b"bar") @@ -39,7 +38,7 @@ def decode(encoded: bytes, encoding: str, errors: str = 'strict') -> Union[str, def decode( - encoded: Union[None, str, bytes], encoding: str, errors: str = 'strict' + encoded: Union[None, str, bytes], encoding: str, errors: str = 'strict' ) -> Union[None, str, bytes]: """ Decode the given input object @@ -56,10 +55,10 @@ def decode( global _cache cached = ( - isinstance(encoded, bytes) and - _cache.encoded == encoded and - _cache.encoding == encoding and - _cache.errors == errors + isinstance(encoded, bytes) and + _cache.encoded == encoded and + _cache.encoding == encoding and + _cache.errors == errors ) if cached: return _cache.decoded @@ -113,10 +112,10 @@ def encode(decoded: Union[None, str, bytes], encoding, errors='strict') -> Union global _cache cached = ( - isinstance(decoded, bytes) and - _cache.decoded == decoded and - _cache.encoding == encoding and - _cache.errors == errors + isinstance(decoded, bytes) and + _cache.decoded == decoded and + _cache.encoding == encoding and + _cache.errors == errors ) if cached: return _cache.encoded diff --git a/mitmproxy/tools/console/flowlist.py b/mitmproxy/tools/console/flowlist.py index b21a16b3b..431870d97 100644 --- a/mitmproxy/tools/console/flowlist.py +++ b/mitmproxy/tools/console/flowlist.py @@ -2,7 +2,7 @@ import urwid from mitmproxy.tools.console import common from mitmproxy.tools.console import layoutwidget -import mitmproxy.tools.console.master # noqa +import mitmproxy.tools.console.master class FlowItem(urwid.WidgetWrap): diff --git a/mitmproxy/tools/console/flowview.py b/mitmproxy/tools/console/flowview.py index 93c9703a8..2da669e9d 100644 --- a/mitmproxy/tools/console/flowview.py +++ b/mitmproxy/tools/console/flowview.py @@ -1,11 +1,11 @@ import math import sys from functools import lru_cache -from typing import Optional, Union # noqa + +import urwid import mitmproxy.flow -import mitmproxy.tools.console.master # noqa -import urwid +import mitmproxy.tools.console.master from mitmproxy import contentviews from mitmproxy import ctx from mitmproxy import http diff --git a/mitmproxy/tools/console/grideditor/__init__.py b/mitmproxy/tools/console/grideditor/__init__.py index 894f3d22c..4a46e9c90 100644 --- a/mitmproxy/tools/console/grideditor/__init__.py +++ b/mitmproxy/tools/console/grideditor/__init__.py @@ -1,2 +1,21 @@ -from .editors import * # noqa -from . import base # noqa +from . import base +from .editors import CookieAttributeEditor, CookieEditor, DataViewer, OptionsEditor, PathEditor, QueryEditor, \ + RequestHeaderEditor, \ + RequestMultipartEditor, \ + RequestUrlEncodedEditor, \ + ResponseHeaderEditor, SetCookieEditor + +__all__ = [ + "base", + "QueryEditor", + "RequestHeaderEditor", + "ResponseHeaderEditor", + "RequestMultipartEditor", + "RequestUrlEncodedEditor", + "PathEditor", + "CookieEditor", + "CookieAttributeEditor", + "SetCookieEditor", + "OptionsEditor", + "DataViewer", +] diff --git a/mitmproxy/tools/console/grideditor/base.py b/mitmproxy/tools/console/grideditor/base.py index d6991877a..d830afb11 100644 --- a/mitmproxy/tools/console/grideditor/base.py +++ b/mitmproxy/tools/console/grideditor/base.py @@ -8,7 +8,7 @@ from mitmproxy.utils import strutils from mitmproxy import exceptions from mitmproxy.tools.console import signals from mitmproxy.tools.console import layoutwidget -import mitmproxy.tools.console.master # noqa +import mitmproxy.tools.console.master def read_file(filename: str, escaped: bool) -> typing.AnyStr: diff --git a/mitmproxy/tools/console/palettes.py b/mitmproxy/tools/console/palettes.py index 571358864..2b18d83d6 100644 --- a/mitmproxy/tools/console/palettes.py +++ b/mitmproxy/tools/console/palettes.py @@ -1,4 +1,4 @@ -import typing # noqa +import typing # Low-color themes should ONLY use the standard foreground and background # colours listed here: # diff --git a/mitmproxy/tools/console/statusbar.py b/mitmproxy/tools/console/statusbar.py index 89bda0569..bd481cac5 100644 --- a/mitmproxy/tools/console/statusbar.py +++ b/mitmproxy/tools/console/statusbar.py @@ -3,7 +3,7 @@ from typing import Optional import urwid -import mitmproxy.tools.console.master # noqa +import mitmproxy.tools.console.master from mitmproxy.tools.console import commandexecutor from mitmproxy.tools.console import common from mitmproxy.tools.console import signals From 9d1e3107e851b3187c1270df189da74236e447f7 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Tue, 29 Mar 2022 14:00:41 +0200 Subject: [PATCH 2/2] `pyupgrade --keep-runtime-typing --py38-plus` --- examples/addons/commands-paths.py | 2 +- examples/addons/websocket-inject-message.py | 2 +- examples/contrib/ntlm_upstream_proxy.py | 17 +++++++++-------- mitmproxy/addons/core.py | 4 ++-- mitmproxy/addons/export.py | 2 +- mitmproxy/addons/serverplayback.py | 2 +- mitmproxy/command.py | 4 ++-- mitmproxy/contentviews/css.py | 2 +- mitmproxy/contentviews/graphql.py | 2 +- mitmproxy/contentviews/grpc.py | 18 +++++++----------- mitmproxy/contentviews/image/image_parser.py | 17 +++++++++-------- mitmproxy/flowfilter.py | 4 ++-- mitmproxy/http.py | 4 ++-- mitmproxy/io/tnetstring.py | 2 +- mitmproxy/proxy/layers/websocket.py | 2 +- mitmproxy/proxy/server.py | 2 +- mitmproxy/tcp.py | 2 +- mitmproxy/tools/console/eventlog.py | 2 +- mitmproxy/tools/console/master.py | 2 +- mitmproxy/tools/console/overlay.py | 2 +- mitmproxy/tools/main.py | 2 +- mitmproxy/tools/web/app.py | 2 +- mitmproxy/utils/debug.py | 2 +- mitmproxy/utils/human.py | 16 ++++++++-------- mitmproxy/utils/strutils.py | 6 +++--- release/cibuild.py | 2 +- test/full_coverage_plugin.py | 2 +- test/mitmproxy/io/test_tnetstring.py | 2 +- .../proxy/layers/http/hyper_h2_test_helpers.py | 2 +- test/mitmproxy/proxy/layers/http/test_http.py | 6 +++--- test/mitmproxy/proxy/layers/test_websocket.py | 4 ++-- test/mitmproxy/test_certs.py | 10 +++++----- 32 files changed, 74 insertions(+), 76 deletions(-) diff --git a/examples/addons/commands-paths.py b/examples/addons/commands-paths.py index ea3431c34..377e5080d 100644 --- a/examples/addons/commands-paths.py +++ b/examples/addons/commands-paths.py @@ -21,7 +21,7 @@ class MyAddon: totals[f.request.host] = totals.setdefault(f.request.host, 0) + 1 with open(path, "w+") as fp: - for cnt, dom in sorted([(v, k) for (k, v) in totals.items()]): + for cnt, dom in sorted((v, k) for (k, v) in totals.items()): fp.write(f"{cnt}: {dom}\n") ctx.log.alert("done") diff --git a/examples/addons/websocket-inject-message.py b/examples/addons/websocket-inject-message.py index 5542879ea..e0a5c1667 100644 --- a/examples/addons/websocket-inject-message.py +++ b/examples/addons/websocket-inject-message.py @@ -15,7 +15,7 @@ def websocket_message(flow: http.HTTPFlow): last_message = flow.websocket.messages[-1] if last_message.is_text and "secret" in last_message.text: last_message.drop() - ctx.master.commands.call("inject.websocket", flow, last_message.from_client, "ssssssh".encode()) + ctx.master.commands.call("inject.websocket", flow, last_message.from_client, b"ssssssh") # Complex example: Schedule a periodic timer diff --git a/examples/contrib/ntlm_upstream_proxy.py b/examples/contrib/ntlm_upstream_proxy.py index 21c1748db..da914d25a 100644 --- a/examples/contrib/ntlm_upstream_proxy.py +++ b/examples/contrib/ntlm_upstream_proxy.py @@ -3,14 +3,15 @@ import binascii import socket import typing +from ntlm_auth import gss_channel_bindings, ntlm + +from mitmproxy import addonmanager, http from mitmproxy import ctx -from mitmproxy import http, addonmanager from mitmproxy.net.http import http1 -from mitmproxy.proxy import layer, commands +from mitmproxy.proxy import commands, layer from mitmproxy.proxy.context import Context from mitmproxy.proxy.layers.http import HttpConnectUpstreamHook, HttpLayer, HttpStream from mitmproxy.proxy.layers.http._upstream_proxy import HttpUpstreamProxy -from ntlm_auth import gss_channel_bindings, ntlm class NTLMUpstreamAuth: @@ -148,7 +149,7 @@ class CustomNTLMContext: ntlm_compatibility: int = ctx.options.upstream_ntlm_compatibility username, password = tuple(auth.split(":")) workstation = socket.gethostname().upper() - ctx.log.debug('\nntlm context with the details: "{}\\{}", *****'.format(domain, username)) + ctx.log.debug(f'\nntlm context with the details: "{domain}\\{username}", *****') self.ctx_log = ctx.log self.preferred_type = preferred_type self.ntlm_context = ntlm.NtlmContext( @@ -163,7 +164,7 @@ class CustomNTLMContext: negotiate_message = self.ntlm_context.step() negotiate_message_base_64_in_bytes = base64.b64encode(negotiate_message) negotiate_message_base_64_ascii = negotiate_message_base_64_in_bytes.decode("ascii") - negotiate_message_base_64_final = u'%s %s' % (self.preferred_type, negotiate_message_base_64_ascii) + negotiate_message_base_64_final = f'{self.preferred_type} {negotiate_message_base_64_ascii}' self.ctx_log.debug( f'{self.preferred_type} Authentication, negotiate message: {negotiate_message_base_64_final}' ) @@ -174,11 +175,11 @@ class CustomNTLMContext: try: challenge_message_ascii_bytes = base64.b64decode(challenge_message, validate=True) except binascii.Error as err: - self.ctx_log.debug('{} Authentication fail with error {}'.format(self.preferred_type, err.__str__())) + self.ctx_log.debug(f'{self.preferred_type} Authentication fail with error {err.__str__()}') return False authenticate_message = self.ntlm_context.step(challenge_message_ascii_bytes) - negotiate_message_base_64 = u'%s %s' % (self.preferred_type, - base64.b64encode(authenticate_message).decode('ascii')) + negotiate_message_base_64 = '{} {}'.format(self.preferred_type, + base64.b64encode(authenticate_message).decode('ascii')) self.ctx_log.debug( f'{self.preferred_type} Authentication, response to challenge message: {negotiate_message_base_64}' ) diff --git a/mitmproxy/addons/core.py b/mitmproxy/addons/core.py index 97284c4cf..9ac76fe45 100644 --- a/mitmproxy/addons/core.py +++ b/mitmproxy/addons/core.py @@ -178,7 +178,7 @@ class Core: req.url = val except ValueError as e: raise exceptions.CommandError( - "URL {} is invalid: {}".format(repr(val), e) + f"URL {repr(val)} is invalid: {e}" ) from e else: self.rupdate = False @@ -199,7 +199,7 @@ class Core: updated.append(f) ctx.master.addons.trigger(hooks.UpdateHook(updated)) - ctx.log.alert("Set {} on {} flows.".format(attr, len(updated))) + ctx.log.alert(f"Set {attr} on {len(updated)} flows.") @command.command("flow.decode") def decode(self, flows: typing.Sequence[flow.Flow], part: str) -> None: diff --git a/mitmproxy/addons/export.py b/mitmproxy/addons/export.py index 10c530623..3635bd0d3 100644 --- a/mitmproxy/addons/export.py +++ b/mitmproxy/addons/export.py @@ -63,7 +63,7 @@ def curl_command(f: flow.Flow) -> str: server_addr = f.server_conn.peername[0] if f.server_conn.peername else None if ctx.options.export_preserve_original_ip and server_addr and request.pretty_host != server_addr: - resolve = "{}:{}:[{}]".format(request.pretty_host, request.port, server_addr) + resolve = f"{request.pretty_host}:{request.port}:[{server_addr}]" args.append("--resolve") args.append(resolve) diff --git a/mitmproxy/addons/serverplayback.py b/mitmproxy/addons/serverplayback.py index 144ec6b9e..91ec1fdb7 100644 --- a/mitmproxy/addons/serverplayback.py +++ b/mitmproxy/addons/serverplayback.py @@ -112,7 +112,7 @@ class ServerPlayback: @command.command("replay.server.count") def count(self) -> int: - return sum([len(i) for i in self.flowmap.values()]) + return sum(len(i) for i in self.flowmap.values()) def _hash(self, flow: http.HTTPFlow) -> typing.Hashable: """ diff --git a/mitmproxy/command.py b/mitmproxy/command.py index c4389a366..afbaad308 100644 --- a/mitmproxy/command.py +++ b/mitmproxy/command.py @@ -265,11 +265,11 @@ class CommandManager: parts, _ = self.parse_partial(cmdstr) if not parts: raise exceptions.CommandError(f"Invalid command: {cmdstr!r}") - command_name, *args = [ + command_name, *args = ( unquote(part.value) for part in parts if part.type != mitmproxy.types.Space - ] + ) return self.call_strings(command_name, args) def dump(self, out=sys.stdout) -> None: diff --git a/mitmproxy/contentviews/css.py b/mitmproxy/contentviews/css.py index 92a855a8d..9eb056eeb 100644 --- a/mitmproxy/contentviews/css.py +++ b/mitmproxy/contentviews/css.py @@ -67,4 +67,4 @@ if __name__ == "__main__": # pragma: no cover t = time.time() x = beautify(data) - print("Beautifying vendor.css took {:.2}s".format(time.time() - t)) + print(f"Beautifying vendor.css took {time.time() - t:.2}s") diff --git a/mitmproxy/contentviews/graphql.py b/mitmproxy/contentviews/graphql.py index cbf56e3d8..149a32bd7 100644 --- a/mitmproxy/contentviews/graphql.py +++ b/mitmproxy/contentviews/graphql.py @@ -20,7 +20,7 @@ def format_query_list(data: typing.List[typing.Any]): num_queries = len(data) - 1 result = "" for i, op in enumerate(data): - result += "--- {i}/{num_queries}\n".format(i=i, num_queries=num_queries) + result += f"--- {i}/{num_queries}\n" result += format_graphql(op) return result diff --git a/mitmproxy/contentviews/grpc.py b/mitmproxy/contentviews/grpc.py index a28a6821b..22362bfe1 100644 --- a/mitmproxy/contentviews/grpc.py +++ b/mitmproxy/contentviews/grpc.py @@ -200,7 +200,7 @@ class ProtoParser: # read field key (tag and wire_type) offset, key = ProtoParser._read_base128le(wire_data[pos:]) # casting raises exception for invalid WireTypes - wt = ProtoParser.WireTypes((key & 7)) + wt = ProtoParser.WireTypes(key & 7) tag = (key >> 3) pos += offset @@ -232,7 +232,7 @@ class ProtoParser: wt == ProtoParser.WireTypes.group_start or wt == ProtoParser.WireTypes.group_end ): - raise ValueError("deprecated field: {}".format(wt)) + raise ValueError(f"deprecated field: {wt}") elif wt == ProtoParser.WireTypes.bit_32: offset, val = ProtoParser._read_u32(wire_data[pos:]) pos += offset @@ -735,8 +735,7 @@ class ProtoParser: yield field_desc_dict # add sub-fields of messages or packed fields for f in decoded_val: - for field_dict in f.gen_flat_decoded_field_dicts(): - yield field_dict + yield from f.gen_flat_decoded_field_dicts() else: field_desc_dict["val"] = decoded_val yield field_desc_dict @@ -767,8 +766,7 @@ class ProtoParser: def gen_flat_decoded_field_dicts(self) -> Generator[Dict, None, None]: for f in self.root_fields: - for field_dict in f.gen_flat_decoded_field_dicts(): - yield field_dict + yield from f.gen_flat_decoded_field_dicts() def gen_str_rows(self) -> Generator[Tuple[str, ...], None, None]: for field_dict in self.gen_flat_decoded_field_dicts(): @@ -879,8 +877,7 @@ def hack_generator_to_list(generator_func): def format_pbuf(message: bytes, parser_options: ProtoParser.ParserOptions, rules: List[ProtoParser.ParserRule]): - for l in format_table(ProtoParser(data=message, parser_options=parser_options, rules=rules).gen_str_rows()): - yield l + yield from format_table(ProtoParser(data=message, parser_options=parser_options, rules=rules).gen_str_rows()) def format_grpc( @@ -895,12 +892,11 @@ def format_grpc( compression_scheme if compressed else compressed) + ')' yield [("text", headline)] - for l in format_pbuf( + yield from format_pbuf( message=pb_message, parser_options=parser_options, rules=rules - ): - yield l + ) @dataclass diff --git a/mitmproxy/contentviews/image/image_parser.py b/mitmproxy/contentviews/image/image_parser.py index 146022c63..7c3437798 100644 --- a/mitmproxy/contentviews/image/image_parser.py +++ b/mitmproxy/contentviews/image/image_parser.py @@ -3,10 +3,10 @@ import typing from kaitaistruct import KaitaiStream -from mitmproxy.contrib.kaitaistruct import png from mitmproxy.contrib.kaitaistruct import gif -from mitmproxy.contrib.kaitaistruct import jpeg from mitmproxy.contrib.kaitaistruct import ico +from mitmproxy.contrib.kaitaistruct import jpeg +from mitmproxy.contrib.kaitaistruct import png Metadata = typing.List[typing.Tuple[str, str]] @@ -91,12 +91,13 @@ def parse_ico(data: bytes) -> Metadata: for i, image in enumerate(img.images): parts.append( ( - 'Image {}'.format(i + 1), "Size: {} x {}\n" - "{: >18}Bits per pixel: {}\n" - "{: >18}PNG: {}".format(256 if not image.width else image.width, - 256 if not image.height else image.height, - '', image.bpp, - '', image.is_png) + f'Image {i + 1}', + "Size: {} x {}\n" + "{: >18}Bits per pixel: {}\n" + "{: >18}PNG: {}".format(256 if not image.width else image.width, + 256 if not image.height else image.height, + '', image.bpp, + '', image.is_png) ) ) diff --git a/mitmproxy/flowfilter.py b/mitmproxy/flowfilter.py index da3f9d0d8..5af486b4e 100644 --- a/mitmproxy/flowfilter.py +++ b/mitmproxy/flowfilter.py @@ -376,7 +376,7 @@ class FSrc(_Rex): def __call__(self, f): if not f.client_conn or not f.client_conn.peername: return False - r = "{}:{}".format(f.client_conn.peername[0], f.client_conn.peername[1]) + r = f"{f.client_conn.peername[0]}:{f.client_conn.peername[1]}" return f.client_conn.peername and self.re.search(r) @@ -388,7 +388,7 @@ class FDst(_Rex): def __call__(self, f): if not f.server_conn or not f.server_conn.address: return False - r = "{}:{}".format(f.server_conn.address[0], f.server_conn.address[1]) + r = f"{f.server_conn.address[0]}:{f.server_conn.address[1]}" return f.server_conn.address and self.re.search(r) diff --git a/mitmproxy/http.py b/mitmproxy/http.py index 743c46c99..d6099826e 100644 --- a/mitmproxy/http.py +++ b/mitmproxy/http.py @@ -510,7 +510,7 @@ class Message(serializable.Serializable): self.headers["content-encoding"] = encoding self.content = self.raw_content if "content-encoding" not in self.headers: - raise ValueError("Invalid content encoding {}".format(repr(encoding))) + raise ValueError(f"Invalid content encoding {repr(encoding)}") def json(self, **kwargs: Any) -> Any: """ @@ -1033,7 +1033,7 @@ class Response(Message): reason = reason.encode("ascii", "strict") if isinstance(content, str): - raise ValueError("Content must be bytes, not {}".format(type(content).__name__)) + raise ValueError(f"Content must be bytes, not {type(content).__name__}") if not isinstance(headers, Headers): headers = Headers(headers) if trailers is not None and not isinstance(trailers, Headers): diff --git a/mitmproxy/io/tnetstring.py b/mitmproxy/io/tnetstring.py index bfe06c0cd..bcb18f93c 100644 --- a/mitmproxy/io/tnetstring.py +++ b/mitmproxy/io/tnetstring.py @@ -146,7 +146,7 @@ def _rdumpq(q: collections.deque, size: int, value: TSerializable) -> int: write(span) return size + 1 + len(span) else: - raise ValueError("unserializable object: {} ({})".format(value, type(value))) + raise ValueError(f"unserializable object: {value} ({type(value)})") def loads(string: bytes) -> TSerializable: diff --git a/mitmproxy/proxy/layers/websocket.py b/mitmproxy/proxy/layers/websocket.py index a31e8316e..7f91be6d9 100644 --- a/mitmproxy/proxy/layers/websocket.py +++ b/mitmproxy/proxy/layers/websocket.py @@ -63,7 +63,7 @@ class WebsocketConnection(wsproto.Connection): frame_buf: List[bytes] def __init__(self, *args, conn: connection.Connection, **kwargs): - super(WebsocketConnection, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.conn = conn self.frame_buf = [b""] diff --git a/mitmproxy/proxy/server.py b/mitmproxy/proxy/server.py index 11e3b92de..957091a48 100644 --- a/mitmproxy/proxy/server.py +++ b/mitmproxy/proxy/server.py @@ -153,7 +153,7 @@ class ConnectionHandler(metaclass=abc.ABCMeta): try: command.connection.timestamp_start = time.time() reader, writer = await asyncio.open_connection(*command.connection.address) - except (IOError, asyncio.CancelledError) as e: + except (OSError, asyncio.CancelledError) as e: err = str(e) if not err: # str(CancelledError()) returns empty string. err = "connection cancelled" diff --git a/mitmproxy/tcp.py b/mitmproxy/tcp.py index a6aea64b8..672321e4b 100644 --- a/mitmproxy/tcp.py +++ b/mitmproxy/tcp.py @@ -55,7 +55,7 @@ class TCPFlow(flow.Flow): _stateobject_attributes["messages"] = List[TCPMessage] def __repr__(self): - return "".format(len(self.messages)) + return f"" __all__ = [ diff --git a/mitmproxy/tools/console/eventlog.py b/mitmproxy/tools/console/eventlog.py index 9063066ae..bc40b6513 100644 --- a/mitmproxy/tools/console/eventlog.py +++ b/mitmproxy/tools/console/eventlog.py @@ -46,7 +46,7 @@ class EventLog(urwid.ListBox, layoutwidget.LayoutWidget): def add_event(self, event_store, entry: log.LogEntry): if log.log_tier(self.master.options.console_eventlog_verbosity) < log.log_tier(entry.level): return - txt = "{}: {}".format(entry.level, str(entry.msg)) + txt = f"{entry.level}: {str(entry.msg)}" if entry.level in ("error", "warn", "alert"): e = urwid.Text((entry.level, txt)) else: diff --git a/mitmproxy/tools/console/master.py b/mitmproxy/tools/console/master.py index 2fc286061..11a738fcf 100644 --- a/mitmproxy/tools/console/master.py +++ b/mitmproxy/tools/console/master.py @@ -89,7 +89,7 @@ class ConsoleMaster(master.Master): signals.status_message.send( message = ( entry.level, - "{}: {}".format(entry.level.title(), str(entry.msg).lstrip()) + f"{entry.level.title()}: {str(entry.msg).lstrip()}" ), expire=5 ) diff --git a/mitmproxy/tools/console/overlay.py b/mitmproxy/tools/console/overlay.py index 8b195703c..3531160ea 100644 --- a/mitmproxy/tools/console/overlay.py +++ b/mitmproxy/tools/console/overlay.py @@ -108,7 +108,7 @@ class Chooser(urwid.WidgetWrap, layoutwidget.LayoutWidget): self.master = master self.choices = choices self.callback = callback - choicewidth = max([len(i) for i in choices]) + choicewidth = max(len(i) for i in choices) self.width = max(choicewidth, len(title)) + 7 self.walker = ChooserListWalker(choices, current) diff --git a/mitmproxy/tools/main.py b/mitmproxy/tools/main.py index abb5e4bac..6771cb1ae 100644 --- a/mitmproxy/tools/main.py +++ b/mitmproxy/tools/main.py @@ -100,7 +100,7 @@ def run( opts.update(**extra(args)) except exceptions.OptionsError as e: - print("{}: {}".format(sys.argv[0], e), file=sys.stderr) + print(f"{sys.argv[0]}: {e}", file=sys.stderr) sys.exit(1) loop = asyncio.get_running_loop() diff --git a/mitmproxy/tools/web/app.py b/mitmproxy/tools/web/app.py index 8746c7e8e..8d4a63866 100644 --- a/mitmproxy/tools/web/app.py +++ b/mitmproxy/tools/web/app.py @@ -206,7 +206,7 @@ class RequestHandler(tornado.web.RequestHandler): try: return json.loads(self.request.body.decode()) except Exception as e: - raise APIError(400, "Malformed JSON: {}".format(str(e))) + raise APIError(400, f"Malformed JSON: {str(e)}") @property def filecontents(self): diff --git a/mitmproxy/utils/debug.py b/mitmproxy/utils/debug.py index 58e1848a2..1bec66b90 100644 --- a/mitmproxy/utils/debug.py +++ b/mitmproxy/utils/debug.py @@ -20,7 +20,7 @@ def dump_system_info(): data = [ f"Mitmproxy: {mitmproxy_version}", f"Python: {platform.python_version()}", - "OpenSSL: {}".format(SSL.SSLeay_version(SSL.SSLEAY_VERSION).decode()), + f"OpenSSL: {SSL.SSLeay_version(SSL.SSLEAY_VERSION).decode()}", f"Platform: {platform.platform()}", ] return "\n".join(data) diff --git a/mitmproxy/utils/human.py b/mitmproxy/utils/human.py index 1c9654b5b..48d1d97a8 100644 --- a/mitmproxy/utils/human.py +++ b/mitmproxy/utils/human.py @@ -31,7 +31,7 @@ def pretty_size(size: int) -> str: raise AssertionError -@functools.lru_cache() +@functools.lru_cache def parse_size(s: typing.Optional[str]) -> typing.Optional[int]: """ Parse a size with an optional k/m/... suffix. @@ -65,7 +65,7 @@ def pretty_duration(secs: typing.Optional[float]) -> str: if secs >= limit: return formatter.format(secs) # less than 1 sec - return "{:.0f}ms".format(secs * 1000) + return f"{secs * 1000:.0f}ms" def format_timestamp(s): @@ -79,7 +79,7 @@ def format_timestamp_with_milli(s): return d.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3] -@functools.lru_cache() +@functools.lru_cache def format_address(address: typing.Optional[tuple]) -> str: """ This function accepts IPv4/IPv6 tuples and @@ -90,12 +90,12 @@ def format_address(address: typing.Optional[tuple]) -> str: try: host = ipaddress.ip_address(address[0]) if host.is_unspecified: - return "*:{}".format(address[1]) + return f"*:{address[1]}" if isinstance(host, ipaddress.IPv4Address): - return "{}:{}".format(str(host), address[1]) + return f"{str(host)}:{address[1]}" # If IPv6 is mapped to IPv4 elif host.ipv4_mapped: - return "{}:{}".format(str(host.ipv4_mapped), address[1]) - return "[{}]:{}".format(str(host), address[1]) + return f"{str(host.ipv4_mapped)}:{address[1]}" + return f"[{str(host)}]:{address[1]}" except ValueError: - return "{}:{}".format(address[0], address[1]) + return f"{address[0]}:{address[1]}" diff --git a/mitmproxy/utils/strutils.py b/mitmproxy/utils/strutils.py index 0622b737d..b6f03c1a0 100644 --- a/mitmproxy/utils/strutils.py +++ b/mitmproxy/utils/strutils.py @@ -22,7 +22,7 @@ def always_bytes(str_or_bytes: Union[None, str, bytes], *encode_args) -> Union[N elif isinstance(str_or_bytes, str): return str_or_bytes.encode(*encode_args) else: - raise TypeError("Expected str or bytes, but got {}.".format(type(str_or_bytes).__name__)) + raise TypeError(f"Expected str or bytes, but got {type(str_or_bytes).__name__}.") @overload @@ -45,7 +45,7 @@ def always_str(str_or_bytes: Union[None, str, bytes], *decode_args) -> Union[Non elif isinstance(str_or_bytes, bytes): return str_or_bytes.decode(*decode_args) else: - raise TypeError("Expected str or bytes, but got {}.".format(type(str_or_bytes).__name__)) + raise TypeError(f"Expected str or bytes, but got {type(str_or_bytes).__name__}.") # Translate control characters to "safe" characters. This implementation @@ -73,7 +73,7 @@ def escape_control_characters(text: str, keep_spacing=True) -> str: keep_spacing: If True, tabs and newlines will not be replaced. """ if not isinstance(text, str): - raise ValueError("text type must be unicode but is {}".format(type(text).__name__)) + raise ValueError(f"text type must be unicode but is {type(text).__name__}") trans = _control_char_trans_newline if keep_spacing else _control_char_trans return text.translate(trans) diff --git a/release/cibuild.py b/release/cibuild.py index 318623e82..13c7c5db7 100755 --- a/release/cibuild.py +++ b/release/cibuild.py @@ -388,7 +388,7 @@ def build_pyinstaller(be: BuildEnviron) -> None: # pragma: no cover click.echo(subprocess.check_output([executable, "--version"]).decode()) archive.add(str(executable), str(executable.name)) - click.echo("Packed {}.".format(be.archive_path.name)) + click.echo(f"Packed {be.archive_path.name}.") def build_wininstaller(be: BuildEnviron) -> None: # pragma: no cover diff --git a/test/full_coverage_plugin.py b/test/full_coverage_plugin.py index c7b05cf68..5cc0e844b 100644 --- a/test/full_coverage_plugin.py +++ b/test/full_coverage_plugin.py @@ -108,7 +108,7 @@ def pytest_terminal_summary(terminalreporter, exitstatus, config): terminalreporter.write(msg, **markup) for name in sorted(coverage_values.keys()): - msg = 'Coverage for {}: {:.2f}%\n'.format(name, coverage_values[name][0]) + msg = f'Coverage for {name}: {coverage_values[name][0]:.2f}%\n' if coverage_values[name][0] < 100: markup = {'red': True, 'bold': True} for s, v in sorted(coverage_values[name][1]): diff --git a/test/mitmproxy/io/test_tnetstring.py b/test/mitmproxy/io/test_tnetstring.py index ecca5130b..14959b9ed 100644 --- a/test/mitmproxy/io/test_tnetstring.py +++ b/test/mitmproxy/io/test_tnetstring.py @@ -62,7 +62,7 @@ def get_random_object(random=random, depth=0): else: return -1 * random.randint(0, MAXINT) n = random.randint(0, 100) - return bytes([random.randint(32, 126) for _ in range(n)]) + return bytes(random.randint(32, 126) for _ in range(n)) class Test_Format(unittest.TestCase): diff --git a/test/mitmproxy/proxy/layers/http/hyper_h2_test_helpers.py b/test/mitmproxy/proxy/layers/http/hyper_h2_test_helpers.py index 7302e58ac..2078b25d4 100644 --- a/test/mitmproxy/proxy/layers/http/hyper_h2_test_helpers.py +++ b/test/mitmproxy/proxy/layers/http/hyper_h2_test_helpers.py @@ -22,7 +22,7 @@ SAMPLE_SETTINGS = { } -class FrameFactory(object): +class FrameFactory: """ A class containing lots of helper methods and state to build frames. This allows test cases to easily build correct HTTP/2 frames to feed to diff --git a/test/mitmproxy/proxy/layers/http/test_http.py b/test/mitmproxy/proxy/layers/http/test_http.py index 32b1d07ae..0851ee068 100644 --- a/test/mitmproxy/proxy/layers/http/test_http.py +++ b/test/mitmproxy/proxy/layers/http/test_http.py @@ -1312,9 +1312,9 @@ def test_invalid_content_length(tctx): flow = Placeholder(HTTPFlow) assert ( Playbook(http.HttpLayer(tctx, HTTPMode.regular)) - >> DataReceived(tctx.client, ("GET http://example.com/ HTTP/1.1\r\n" - "Host: example.com\r\n" - "Content-Length: NaN\r\n\r\n").encode()) + >> DataReceived(tctx.client, (b"GET http://example.com/ HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Content-Length: NaN\r\n\r\n")) << SendData(tctx.client, err) << CloseConnection(tctx.client) << http.HttpRequestHeadersHook(flow) diff --git a/test/mitmproxy/proxy/layers/test_websocket.py b/test/mitmproxy/proxy/layers/test_websocket.py index e531e1210..ecbfeee7f 100644 --- a/test/mitmproxy/proxy/layers/test_websocket.py +++ b/test/mitmproxy/proxy/layers/test_websocket.py @@ -27,7 +27,7 @@ class _Masked: other[1] &= 0b0111_1111 # remove mask bit assert other[1] < 126 # (we don't support extended payload length here) mask = other[2:6] - payload = bytes([x ^ mask[i % 4] for i, x in enumerate(other[6:])]) + payload = bytes(x ^ mask[i % 4] for i, x in enumerate(other[6:])) return self.unmasked == other[:2] + payload @@ -41,7 +41,7 @@ def masked_bytes(unmasked: bytes) -> bytes: assert header[1] < 126 # assert that this is neither masked nor extended payload header[1] |= 0b1000_0000 mask = secrets.token_bytes(4) - masked = bytes([x ^ mask[i % 4] for i, x in enumerate(unmasked[2:])]) + masked = bytes(x ^ mask[i % 4] for i, x in enumerate(unmasked[2:])) return bytes(header + mask + masked) diff --git a/test/mitmproxy/test_certs.py b/test/mitmproxy/test_certs.py index 1084b0a41..ac5a01fb1 100644 --- a/test/mitmproxy/test_certs.py +++ b/test/mitmproxy/test_certs.py @@ -264,13 +264,13 @@ class TestCert: def test_multi_valued_rdns(self, tdata): subject = x509.Name([ x509.RelativeDistinguishedName([ - x509.NameAttribute(NameOID.TITLE, u'Test'), - x509.NameAttribute(NameOID.COMMON_NAME, u'Multivalue'), - x509.NameAttribute(NameOID.SURNAME, u'RDNs'), - x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'TSLA'), + x509.NameAttribute(NameOID.TITLE, 'Test'), + x509.NameAttribute(NameOID.COMMON_NAME, 'Multivalue'), + x509.NameAttribute(NameOID.SURNAME, 'RDNs'), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'TSLA'), ]), x509.RelativeDistinguishedName([ - x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA') + x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'PyCA') ]), ]) expected = [('2.5.4.12', 'Test'), ('CN', 'Multivalue'), ('2.5.4.4', 'RDNs'), ('O', 'TSLA'), ('O', 'PyCA')]