Skip to content

Commit 80204f9

Browse files
authored
Fix type checking of Union parameters (#495)
1 parent cc5931b commit 80204f9

3 files changed

Lines changed: 21 additions & 7 deletions

File tree

‎poucave/app.py‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,7 @@ def __init__(
9191
raise ValueError(f"Unknown parameter '{param}' for '{module}'")
9292
# Make sure specifed value matches function param type.
9393
_type = self.func.__annotations__[param]
94-
# Get back to original type (eg. List[str] -> list)
95-
raw_type = getattr(_type, "__origin__", _type)
96-
# Cast to expected type (will raise ValueError)
97-
self.params[param] = raw_type(value)
94+
self.params[param] = utils.cast_value(_type, value)
9895

9996
async def run(self, cache=None, force=False) -> Tuple[Any, bool, Any, int]:
10097
identifier = f"{self.project}/{self.name}"

‎poucave/utils.py‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from contextlib import asynccontextmanager
66
from datetime import datetime, timezone
77
from itertools import chain
8-
from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple
8+
from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple, Union
99

1010
import aiohttp
1111
import backoff
@@ -215,3 +215,20 @@ async def wrapper(request):
215215
return web.json_response(view_result, status=status_code)
216216

217217
return wrapper
218+
219+
220+
def cast_value(_type, value):
221+
# Get back to original type (eg. List[str] -> list)
222+
raw_type = getattr(_type, "__origin__", _type)
223+
if raw_type is Union:
224+
types = [getattr(t, "__origin__", t) for t in _type.__args__]
225+
else:
226+
types = [raw_type]
227+
# Cast to the first compatible type.
228+
while t := types.pop():
229+
try:
230+
return t(value)
231+
except (TypeError, ValueError):
232+
# Wrong parameter type. Raise if no more type to try.
233+
if len(types) == 0:
234+
raise

‎tests/conftest.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import os
2-
from typing import List
2+
from typing import List, Union
33

44
import pytest
55
import responses
@@ -16,7 +16,7 @@
1616
URL_PARAMETERS = ["max_age"]
1717

1818

19-
async def run(max_age: int, from_conf: int, extras: List = []):
19+
async def run(max_age: Union[int, float], from_conf: int, extras: List = []):
2020
"""
2121
Fake check that returns the input parameters.
2222
Used for testing, from `tests/config.toml`.

0 commit comments

Comments
 (0)