change add_option parameter order

name, type, value matches natural language ($x is a bool with a default value of $y)
and also matches the python type annotation order of name: type = value
This commit is contained in:
Maximilian Hils 2017-03-08 00:52:37 +01:00
parent 8707928b16
commit f276c7a80d
4 changed files with 111 additions and 110 deletions

View File

@ -1,8 +1,7 @@
from typing import Optional, Sequence from typing import Optional, Sequence
from mitmproxy.net import tcp
from mitmproxy import optmanager from mitmproxy import optmanager
from mitmproxy.net import tcp
# We redefine these here for now to avoid importing Urwid-related guff on # We redefine these here for now to avoid importing Urwid-related guff on
# platforms that don't support it, and circular imports. We can do better using # platforms that don't support it, and circular imports. We can do better using
@ -29,128 +28,130 @@ LISTEN_PORT = 8080
# We manually need to specify this, otherwise OpenSSL may select a non-HTTP2 cipher by default. # We manually need to specify this, otherwise OpenSSL may select a non-HTTP2 cipher by default.
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=apache-2.2.15&openssl=1.0.2&hsts=yes&profile=old # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=apache-2.2.15&openssl=1.0.2&hsts=yes&profile=old
DEFAULT_CLIENT_CIPHERS = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:" \ DEFAULT_CLIENT_CIPHERS = (
"ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:" \ "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:"
"ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:" \ "ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:"
"ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:" \ "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:"
"DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:" \ "ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:"
"DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:" \ "DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:"
"AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:" \ "DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:"
"HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:" \ "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:"
"HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:"
"!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" "!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
)
class Options(optmanager.OptManager): class Options(optmanager.OptManager):
def __init__(self, **kwargs) -> None: def __init__(self, **kwargs) -> None:
super().__init__() super().__init__()
self.add_option( self.add_option(
"onboarding", True, bool, "onboarding", bool, True,
"Toggle the mitmproxy onboarding app." "Toggle the mitmproxy onboarding app."
) )
self.add_option( self.add_option(
"onboarding_host", APP_HOST, str, "onboarding_host", str, APP_HOST,
""" """
Domain to serve the onboarding app from. For transparent mode, use Domain to serve the onboarding app from. For transparent mode, use
an IP when a DNS entry for the app domain is not present. """ an IP when a DNS entry for the app domain is not present. """
) )
self.add_option( self.add_option(
"onboarding_port", APP_PORT, int, "onboarding_port", int, APP_PORT,
"Port to serve the onboarding app from." "Port to serve the onboarding app from."
) )
self.add_option( self.add_option(
"anticache", False, bool, "anticache", bool, False,
""" """
Strip out request headers that might cause the server to return Strip out request headers that might cause the server to return
304-not-modified. 304-not-modified.
""" """
) )
self.add_option( self.add_option(
"anticomp", False, bool, "anticomp", bool, False,
"Try to convince servers to send us un-compressed data." "Try to convince servers to send us un-compressed data."
) )
self.add_option( self.add_option(
"client_replay", [], Sequence[str], "client_replay", Sequence[str], [],
"Replay client requests from a saved file." "Replay client requests from a saved file."
) )
self.add_option( self.add_option(
"replay_kill_extra", False, bool, "replay_kill_extra", bool, False,
"Kill extra requests during replay." "Kill extra requests during replay."
) )
self.add_option( self.add_option(
"keepserving", True, bool, "keepserving", bool, True,
"Continue serving after client playback or file read." "Continue serving after client playback or file read."
) )
self.add_option( self.add_option(
"server", True, bool, "server", bool, True,
"Start a proxy server." "Start a proxy server."
) )
self.add_option( self.add_option(
"server_replay_nopop", False, bool, "server_replay_nopop", bool, False,
""" """
Disable response pop from response flow. This makes it possible to Disable response pop from response flow. This makes it possible to
replay same response multiple times. replay same response multiple times.
""" """
) )
self.add_option( self.add_option(
"refresh_server_playback", True, bool, "refresh_server_playback", bool, True,
""" """
Refresh server replay responses by adjusting date, expires and Refresh server replay responses by adjusting date, expires and
last-modified headers, as well as adjusting cookie expiration. last-modified headers, as well as adjusting cookie expiration.
""" """
) )
self.add_option( self.add_option(
"rfile", None, Optional[str], "rfile", Optional[str], None,
"Read flows from file." "Read flows from file."
) )
self.add_option( self.add_option(
"scripts", [], Sequence[str], "scripts", Sequence[str], [],
""" """
Execute a script. Execute a script.
""" """
) )
self.add_option( self.add_option(
"showhost", False, bool, "showhost", bool, False,
"Use the Host header to construct URLs for display." "Use the Host header to construct URLs for display."
) )
self.add_option( self.add_option(
"replacements", [], Sequence[str], "replacements", Sequence[str], [],
""" """
Replacement patterns of the form "/pattern/regex/replacement", where Replacement patterns of the form "/pattern/regex/replacement", where
the separator can be any character. the separator can be any character.
""" """
) )
self.add_option( self.add_option(
"replacement_files", [], Sequence[str], "replacement_files", Sequence[str], [],
""" """
Replacement pattern, where the replacement clause is a path to a Replacement pattern, where the replacement clause is a path to a
file. file.
""" """
) )
self.add_option( self.add_option(
"server_replay_use_headers", [], Sequence[str], "server_replay_use_headers", Sequence[str], [],
"Request headers to be considered during replay." "Request headers to be considered during replay."
) )
self.add_option( self.add_option(
"setheaders", [], Sequence[str], "setheaders", Sequence[str], [],
""" """
Header set pattern of the form "/pattern/header/value", where the Header set pattern of the form "/pattern/header/value", where the
separator can be any character. separator can be any character.
""" """
) )
self.add_option( self.add_option(
"server_replay", [], Sequence[str], "server_replay", Sequence[str], [],
"Replay server responses from a saved file." "Replay server responses from a saved file."
) )
self.add_option( self.add_option(
"stickycookie", None, Optional[str], "stickycookie", Optional[str], None,
"Set sticky cookie filter. Matched against requests." "Set sticky cookie filter. Matched against requests."
) )
self.add_option( self.add_option(
"stickyauth", None, Optional[str], "stickyauth", Optional[str], None,
"Set sticky auth filter. Matched against requests." "Set sticky auth filter. Matched against requests."
) )
self.add_option( self.add_option(
"stream_large_bodies", None, Optional[str], "stream_large_bodies", Optional[str], None,
""" """
Stream data to the client if response body exceeds the given Stream data to the client if response body exceeds the given
threshold. If streamed, the body will not be stored in any way. threshold. If streamed, the body will not be stored in any way.
@ -158,30 +159,30 @@ class Options(optmanager.OptManager):
""" """
) )
self.add_option( self.add_option(
"verbosity", 2, int, "verbosity", int, 2,
"Log verbosity." "Log verbosity."
) )
self.add_option( self.add_option(
"default_contentview", "auto", str, "default_contentview", str, "auto",
"The default content view mode." "The default content view mode."
) )
self.add_option( self.add_option(
"streamfile", None, Optional[str], "streamfile", Optional[str], None,
"Write flows to file. Prefix path with + to append." "Write flows to file. Prefix path with + to append."
) )
self.add_option( self.add_option(
"server_replay_ignore_content", False, bool, "server_replay_ignore_content", bool, False,
"Ignore request's content while searching for a saved flow to replay." "Ignore request's content while searching for a saved flow to replay."
) )
self.add_option( self.add_option(
"server_replay_ignore_params", [], Sequence[str], "server_replay_ignore_params", Sequence[str], [],
""" """
Request's parameters to be ignored while searching for a saved flow Request's parameters to be ignored while searching for a saved flow
to replay. Can be passed multiple times. to replay. Can be passed multiple times.
""" """
) )
self.add_option( self.add_option(
"server_replay_ignore_payload_params", [], Sequence[str], "server_replay_ignore_payload_params", Sequence[str], [],
""" """
Request's payload parameters (application/x-www-form-urlencoded or Request's payload parameters (application/x-www-form-urlencoded or
multipart/form-data) to be ignored while searching for a saved flow multipart/form-data) to be ignored while searching for a saved flow
@ -189,7 +190,7 @@ class Options(optmanager.OptManager):
""" """
) )
self.add_option( self.add_option(
"server_replay_ignore_host", False, bool, "server_replay_ignore_host", bool, False,
""" """
Ignore request's destination host while searching for a saved flow Ignore request's destination host while searching for a saved flow
to replay. to replay.
@ -198,7 +199,7 @@ class Options(optmanager.OptManager):
# Proxy options # Proxy options
self.add_option( self.add_option(
"proxyauth", None, Optional[str], "proxyauth", Optional[str], None,
""" """
Require authentication before proxying requests. If the value is Require authentication before proxying requests. If the value is
"any", we prompt for authentication, but permit any values. If it "any", we prompt for authentication, but permit any values. If it
@ -208,25 +209,25 @@ class Options(optmanager.OptManager):
""" """
) )
self.add_option( self.add_option(
"add_upstream_certs_to_client_chain", False, bool, "add_upstream_certs_to_client_chain", bool, False,
""" """
Add all certificates of the upstream server to the certificate chain Add all certificates of the upstream server to the certificate chain
that will be served to the proxy client, as extras. that will be served to the proxy client, as extras.
""" """
) )
self.add_option( self.add_option(
"body_size_limit", None, Optional[str], "body_size_limit", Optional[str], None,
""" """
Byte size limit of HTTP request and response bodies. Understands Byte size limit of HTTP request and response bodies. Understands
k/m/g suffixes, i.e. 3m for 3 megabytes. k/m/g suffixes, i.e. 3m for 3 megabytes.
""" """
) )
self.add_option( self.add_option(
"cadir", CA_DIR, str, "cadir", str, CA_DIR,
"Location of the default mitmproxy CA files." "Location of the default mitmproxy CA files."
) )
self.add_option( self.add_option(
"certs", [], Sequence[str], "certs", Sequence[str], [],
""" """
SSL certificates. SPEC is of the form "[domain=]path". The SSL certificates. SPEC is of the form "[domain=]path". The
domain may include a wildcard, and is equal to "*" if not specified. domain may include a wildcard, and is equal to "*" if not specified.
@ -238,19 +239,19 @@ class Options(optmanager.OptManager):
""" """
) )
self.add_option( self.add_option(
"ciphers_client", DEFAULT_CLIENT_CIPHERS, str, "ciphers_client", str, DEFAULT_CLIENT_CIPHERS,
"Set supported ciphers for client connections using OpenSSL syntax." "Set supported ciphers for client connections using OpenSSL syntax."
) )
self.add_option( self.add_option(
"ciphers_server", None, Optional[str], "ciphers_server", Optional[str], None,
"Set supported ciphers for server connections using OpenSSL syntax." "Set supported ciphers for server connections using OpenSSL syntax."
) )
self.add_option( self.add_option(
"client_certs", None, Optional[str], "client_certs", Optional[str], None,
"Client certificate file or directory." "Client certificate file or directory."
) )
self.add_option( self.add_option(
"ignore_hosts", [], Sequence[str], "ignore_hosts", Sequence[str], [],
""" """
Ignore host and forward all traffic without processing it. In Ignore host and forward all traffic without processing it. In
transparent mode, it is recommended to use an IP address (range), transparent mode, it is recommended to use an IP address (range),
@ -260,19 +261,19 @@ class Options(optmanager.OptManager):
""" """
) )
self.add_option( self.add_option(
"listen_host", "", str, "listen_host", str, "",
"Address to bind proxy to." "Address to bind proxy to."
) )
self.add_option( self.add_option(
"listen_port", LISTEN_PORT, int, "listen_port", int, LISTEN_PORT,
"Proxy service port." "Proxy service port."
) )
self.add_option( self.add_option(
"upstream_bind_address", "", str, "upstream_bind_address", str, "",
"Address to bind upstream requests to." "Address to bind upstream requests to."
) )
self.add_option( self.add_option(
"mode", "regular", str, "mode", str, "regular",
""" """
Mode can be "regular", "transparent", "socks5", "reverse:SPEC", Mode can be "regular", "transparent", "socks5", "reverse:SPEC",
or "upstream:SPEC". For reverse and upstream proxy modes, SPEC or "upstream:SPEC". For reverse and upstream proxy modes, SPEC
@ -280,11 +281,11 @@ class Options(optmanager.OptManager):
""" """
) )
self.add_option( self.add_option(
"upstream_cert", True, bool, "upstream_cert", bool, True,
"Connect to upstream server to look up certificate details." "Connect to upstream server to look up certificate details."
) )
self.add_option( self.add_option(
"keep_host_header", False, bool, "keep_host_header", bool, False,
""" """
Reverse Proxy: Keep the original host header instead of rewriting it Reverse Proxy: Keep the original host header instead of rewriting it
to the reverse proxy target. to the reverse proxy target.
@ -292,12 +293,12 @@ class Options(optmanager.OptManager):
) )
self.add_option( self.add_option(
"http2", True, bool, "http2", bool, True,
"Enable/disable HTTP/2 support. " "Enable/disable HTTP/2 support. "
"HTTP/2 support is enabled by default.", "HTTP/2 support is enabled by default.",
) )
self.add_option( self.add_option(
"http2_priority", False, bool, "http2_priority", bool, False,
""" """
PRIORITY forwarding for HTTP/2 connections. PRIORITY forwarding is PRIORITY forwarding for HTTP/2 connections. PRIORITY forwarding is
disabled by default, because some webservers fail to implement the disabled by default, because some webservers fail to implement the
@ -305,32 +306,32 @@ class Options(optmanager.OptManager):
""" """
) )
self.add_option( self.add_option(
"websocket", True, bool, "websocket", bool, True,
"Enable/disable WebSocket support. " "Enable/disable WebSocket support. "
"WebSocket support is enabled by default.", "WebSocket support is enabled by default.",
) )
self.add_option( self.add_option(
"rawtcp", False, bool, "rawtcp", bool, False,
"Enable/disable experimental raw TCP support. " "Enable/disable experimental raw TCP support. "
"Disabled by default. " "Disabled by default. "
) )
self.add_option( self.add_option(
"spoof_source_address", False, bool, "spoof_source_address", bool, False,
""" """
Use the client's IP for server-side connections. Combine with Use the client's IP for server-side connections. Combine with
--upstream-bind-address to spoof a fixed source address. --upstream-bind-address to spoof a fixed source address.
""" """
) )
self.add_option( self.add_option(
"upstream_auth", None, Optional[str], "upstream_auth", Optional[str], None,
""" """
Add HTTP Basic authentcation to upstream proxy and reverse proxy Add HTTP Basic authentcation to upstream proxy and reverse proxy
requests. Format: username:password. requests. Format: username:password.
""" """
) )
self.add_option( self.add_option(
"ssl_version_client", "secure", str, "ssl_version_client", str, "secure",
""" """
Set supported SSL/TLS versions for client connections. SSLv2, SSLv3 Set supported SSL/TLS versions for client connections. SSLv2, SSLv3
and 'all' are INSECURE. Defaults to secure, which is TLS1.0+. and 'all' are INSECURE. Defaults to secure, which is TLS1.0+.
@ -338,7 +339,7 @@ class Options(optmanager.OptManager):
choices=tcp.sslversion_choices.keys(), choices=tcp.sslversion_choices.keys(),
) )
self.add_option( self.add_option(
"ssl_version_server", "secure", str, "ssl_version_server", str, "secure",
""" """
Set supported SSL/TLS versions for server connections. SSLv2, SSLv3 Set supported SSL/TLS versions for server connections. SSLv2, SSLv3
and 'all' are INSECURE. Defaults to secure, which is TLS1.0+. and 'all' are INSECURE. Defaults to secure, which is TLS1.0+.
@ -346,22 +347,22 @@ class Options(optmanager.OptManager):
choices=tcp.sslversion_choices.keys(), choices=tcp.sslversion_choices.keys(),
) )
self.add_option( self.add_option(
"ssl_insecure", False, bool, "ssl_insecure", bool, False,
"Do not verify upstream server SSL/TLS certificates." "Do not verify upstream server SSL/TLS certificates."
) )
self.add_option( self.add_option(
"ssl_verify_upstream_trusted_cadir", None, Optional[str], "ssl_verify_upstream_trusted_cadir", Optional[str], None,
""" """
Path to a directory of trusted CA certificates for upstream server Path to a directory of trusted CA certificates for upstream server
verification prepared using the c_rehash tool. verification prepared using the c_rehash tool.
""" """
) )
self.add_option( self.add_option(
"ssl_verify_upstream_trusted_ca", None, Optional[str], "ssl_verify_upstream_trusted_ca", Optional[str], None,
"Path to a PEM formatted trusted CA certificate." "Path to a PEM formatted trusted CA certificate."
) )
self.add_option( self.add_option(
"tcp_hosts", [], Sequence[str], "tcp_hosts", Sequence[str], [],
""" """
Generic TCP SSL proxy mode for all hosts that match the pattern. Generic TCP SSL proxy mode for all hosts that match the pattern.
Similar to --ignore, but SSL connections are intercepted. The Similar to --ignore, but SSL connections are intercepted. The
@ -370,72 +371,72 @@ class Options(optmanager.OptManager):
) )
self.add_option( self.add_option(
"intercept", None, Optional[str], "intercept", Optional[str], None,
"Intercept filter expression." "Intercept filter expression."
) )
# Console options # Console options
self.add_option( self.add_option(
"console_eventlog", False, bool, "console_eventlog", bool, False,
"Show event log." "Show event log."
) )
self.add_option( self.add_option(
"console_focus_follow", False, bool, "console_focus_follow", bool, False,
"Focus follows new flows." "Focus follows new flows."
) )
self.add_option( self.add_option(
"console_palette", "dark", str, "console_palette", str, "dark",
"Color palette.", "Color palette.",
choices=sorted(console_palettes), choices=sorted(console_palettes),
) )
self.add_option( self.add_option(
"console_palette_transparent", False, bool, "console_palette_transparent", bool, False,
"Set transparent background for palette." "Set transparent background for palette."
) )
self.add_option( self.add_option(
"console_mouse", True, bool, "console_mouse", bool, True,
"Console mouse interaction." "Console mouse interaction."
) )
self.add_option( self.add_option(
"console_order", None, Optional[str], "console_order", Optional[str], None,
"Flow sort order.", "Flow sort order.",
choices=view_orders, choices=view_orders,
) )
self.add_option( self.add_option(
"console_order_reversed", False, bool, "console_order_reversed", bool, False,
"Reverse the sorting order." "Reverse the sorting order."
) )
self.add_option( self.add_option(
"filter", None, Optional[str], "filter", Optional[str], None,
"Filter view expression." "Filter view expression."
) )
# Web options # Web options
self.add_option( self.add_option(
"web_open_browser", True, bool, "web_open_browser", bool, True,
"Start a browser." "Start a browser."
) )
self.add_option( self.add_option(
"web_debug", False, bool, "web_debug", bool, False,
"Mitmweb debugging." "Mitmweb debugging."
) )
self.add_option( self.add_option(
"web_port", 8081, int, "web_port", int, 8081,
"Mitmweb port." "Mitmweb port."
) )
self.add_option( self.add_option(
"web_iface", "127.0.0.1", str, "web_iface", str, "127.0.0.1",
"Mitmweb interface." "Mitmweb interface."
) )
# Dump options # Dump options
self.add_option( self.add_option(
"filtstr", None, Optional[str], "filtstr", Optional[str], None,
"The filter string for mitmdump." "The filter string for mitmdump."
) )
self.add_option( self.add_option(
"flow_detail", 1, int, "flow_detail", int, 1,
"Flow detail display level." "Flow detail display level."
) )

View File

@ -26,15 +26,15 @@ class _Option:
def __init__( def __init__(
self, self,
name: str, name: str,
default: typing.Any,
typespec: typing.Type, typespec: typing.Type,
default: typing.Any,
help: str, help: str,
choices: typing.Optional[typing.Sequence[str]] choices: typing.Optional[typing.Sequence[str]]
) -> None: ) -> None:
typecheck.check_type(name, default, typespec) typecheck.check_type(name, default, typespec)
self.name = name self.name = name
self._default = default
self.typespec = typespec self.typespec = typespec
self._default = default
self.value = unset self.value = unset
self.help = help self.help = help
self.choices = choices self.choices = choices
@ -71,7 +71,7 @@ class _Option:
def __deepcopy__(self, _): def __deepcopy__(self, _):
o = _Option( o = _Option(
self.name, self.default, self.typespec, self.help, self.choices self.name, self.typespec, self.default, self.help, self.choices
) )
if self.has_changed(): if self.has_changed():
o.value = self.current() o.value = self.current()
@ -101,14 +101,14 @@ class OptManager:
def add_option( def add_option(
self, self,
name: str, name: str,
default: typing.Any,
typespec: typing.Type, typespec: typing.Type,
default: typing.Any,
help: str, help: str,
choices: typing.Optional[typing.Sequence[str]] = None choices: typing.Optional[typing.Sequence[str]] = None
) -> None: ) -> None:
if name in self._options: if name in self._options:
raise ValueError("Option %s already exists" % name) raise ValueError("Option %s already exists" % name)
self._options[name] = _Option(name, default, typespec, help, choices) self._options[name] = _Option(name, typespec, default, help, choices)
@contextlib.contextmanager @contextlib.contextmanager
def rollback(self, updated, reraise=False): def rollback(self, updated, reraise=False):

View File

@ -39,5 +39,5 @@ def test_modes(m):
sa = core.Core() sa = core.Core()
with taddons.context() as tctx: with taddons.context() as tctx:
tctx.configure(sa, mode = "reverse:http://localhost") tctx.configure(sa, mode = "reverse:http://localhost")
with pytest.raises(Exception, match="Invalid mode"): with pytest.raises(Exception, match="Invalid server specification"):
tctx.configure(sa, mode = "reverse:") tctx.configure(sa, mode = "reverse:")

View File

@ -13,36 +13,36 @@ from mitmproxy.test import tutils
class TO(optmanager.OptManager): class TO(optmanager.OptManager):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.add_option("one", None, typing.Optional[int], "help") self.add_option("one", typing.Optional[int], None, "help")
self.add_option("two", 2, typing.Optional[int], "help") self.add_option("two", typing.Optional[int], 2, "help")
self.add_option("bool", False, bool, "help") self.add_option("bool", bool, False, "help")
class TD(optmanager.OptManager): class TD(optmanager.OptManager):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.add_option("one", "done", str, "help") self.add_option("one", str, "done", "help")
self.add_option("two", "dtwo", str, "help") self.add_option("two", str, "dtwo", "help")
class TD2(TD): class TD2(TD):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.add_option("three", "dthree", str, "help") self.add_option("three", str, "dthree", "help")
self.add_option("four", "dfour", str, "help") self.add_option("four", str, "dfour", "help")
class TM(optmanager.OptManager): class TM(optmanager.OptManager):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.add_option("two", ["foo"], typing.Sequence[str], "help") self.add_option("two", typing.Sequence[str], ["foo"], "help")
self.add_option("one", None, typing.Optional[str], "help") self.add_option("one", typing.Optional[str], None, "help")
def test_add_option(): def test_add_option():
o = TO() o = TO()
with pytest.raises(ValueError, match="already exists"): with pytest.raises(ValueError, match="already exists"):
o.add_option("one", None, typing.Optional[int], "help") o.add_option("one", typing.Optional[int], None, "help")
def test_defaults(): def test_defaults():
@ -76,7 +76,7 @@ def test_defaults():
def test_options(): def test_options():
o = TO() o = TO()
assert o.keys() == set(["bool", "one", "two"]) assert o.keys() == {"bool", "one", "two"}
assert o.one is None assert o.one is None
assert o.two == 2 assert o.two == 2
@ -189,7 +189,7 @@ def test_rollback():
assert rec[3].bool is False assert rec[3].bool is False
with pytest.raises(exceptions.OptionsError): with pytest.raises(exceptions.OptionsError):
with o.rollback(set(["one"]), reraise=True): with o.rollback({"one"}, reraise=True):
raise exceptions.OptionsError() raise exceptions.OptionsError()
@ -270,14 +270,14 @@ def test_merge():
def test_option(): def test_option():
o = optmanager._Option("test", 1, int, None, None) o = optmanager._Option("test", int, 1, None, None)
assert o.current() == 1 assert o.current() == 1
with pytest.raises(TypeError): with pytest.raises(TypeError):
o.set("foo") o.set("foo")
with pytest.raises(TypeError): with pytest.raises(TypeError):
optmanager._Option("test", 1, str, None, None) optmanager._Option("test", str, 1, None, None)
o2 = optmanager._Option("test", 1, int, None, None) o2 = optmanager._Option("test", int, 1, None, None)
assert o2 == o assert o2 == o
o2.set(5) o2.set(5)
assert o2 != o assert o2 != o
@ -291,14 +291,14 @@ def test_dump():
class TTypes(optmanager.OptManager): class TTypes(optmanager.OptManager):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.add_option("str", "str", str, "help") self.add_option("str", str, "str", "help")
self.add_option("optstr", "optstr", typing.Optional[str], "help", "help") self.add_option("optstr", typing.Optional[str], "optstr", "help", "help")
self.add_option("bool", False, bool, "help") self.add_option("bool", bool, False, "help")
self.add_option("bool_on", True, bool, "help") self.add_option("bool_on", bool, True, "help")
self.add_option("int", 0, int, "help") self.add_option("int", int, 0, "help")
self.add_option("optint", 0, typing.Optional[int], "help") self.add_option("optint", typing.Optional[int], 0, "help")
self.add_option("seqstr", [], typing.Sequence[str], "help") self.add_option("seqstr", typing.Sequence[str], [], "help")
self.add_option("unknown", 0.0, float, "help") self.add_option("unknown", float, 0.0, "help")
def test_make_parser(): def test_make_parser():