Add typechecking of Any values for state object

An ugly solution for an ugly little problem. This patch uses JSON's type
checker to validate Any values in stateobject, in order to avoid a circular
import.

Fixes #3180
This commit is contained in:
Aldo Cortesi 2018-06-17 10:22:17 +12:00
parent 3227f67d88
commit 77b49aa8de
2 changed files with 10 additions and 3 deletions

View File

@ -1,6 +1,7 @@
import typing import typing
from typing import Any # noqa from typing import Any # noqa
from typing import MutableMapping # noqa from typing import MutableMapping # noqa
import json
from mitmproxy.coretypes import serializable from mitmproxy.coretypes import serializable
from mitmproxy.utils import typecheck from mitmproxy.utils import typecheck
@ -77,8 +78,14 @@ def _process(typeinfo: typecheck.Type, val: typing.Any, make: bool) -> typing.An
for k, v in val.items() for k, v in val.items()
} }
elif typename.startswith("typing.Any"): elif typename.startswith("typing.Any"):
# FIXME: Remove this when we remove flow.metadata # This requires a bit of explanation. We can't import our IO layer here,
assert isinstance(val, (int, str, bool, bytes)) # because it causes a circular import. Rather than restructuring the
# code for this, we use JSON serialization, which has similar primitive
# type restrictions as tnetstring, to check for conformance.
try:
json.dumps(val)
except TypeError:
raise ValueError(f"Data not serializable: {val}")
return val return val
else: else:
return typeinfo(val) return typeinfo(val)

View File

@ -125,7 +125,7 @@ def test_any():
assert a.x == b.x assert a.x == b.x
a = TAny(object()) a = TAny(object())
with pytest.raises(AssertionError): with pytest.raises(ValueError):
a.get_state() a.get_state()