my.core: more work on typing @warn_if_empty, extra test
This commit is contained in:
parent
4b22d17188
commit
e3a71ea6c6
2 changed files with 33 additions and 18 deletions
|
@ -273,6 +273,7 @@ def get_valid_filename(s: str) -> str:
|
||||||
from typing import Generic, Sized, Callable
|
from typing import Generic, Sized, Callable
|
||||||
|
|
||||||
|
|
||||||
|
# X = TypeVar('X')
|
||||||
def _warn_iterator(it):
|
def _warn_iterator(it):
|
||||||
emitted = False
|
emitted = False
|
||||||
for i in it:
|
for i in it:
|
||||||
|
@ -281,27 +282,23 @@ def _warn_iterator(it):
|
||||||
if not emitted:
|
if not emitted:
|
||||||
warnings.warn(f"Function hasn't emitted any data, make sure your config paths are correct")
|
warnings.warn(f"Function hasn't emitted any data, make sure your config paths are correct")
|
||||||
|
|
||||||
|
# todo need to popretly restrict to a container... ugh
|
||||||
def _warn_iterable(it):
|
C = TypeVar('C')
|
||||||
|
def _warn_iterable(it: C) -> C:
|
||||||
if isinstance(it, Sized):
|
if isinstance(it, Sized):
|
||||||
sz = len(it)
|
sz = len(it)
|
||||||
if sz == 0:
|
if sz == 0:
|
||||||
warnings.warn(f"Function is returning empty container, make sure your config paths are correct")
|
warnings.warn(f"Function is returning empty container, make sure your config paths are correct")
|
||||||
return it
|
return it # type: ignore[return-value]
|
||||||
else:
|
else:
|
||||||
return _warn_iterator(it)
|
return _warn_iterator(it)
|
||||||
|
|
||||||
|
|
||||||
from functools import wraps
|
CC = TypeVar('CC')
|
||||||
X = TypeVar('X')
|
|
||||||
|
|
||||||
class G(Generic[X], Iterable[X]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
CC = Callable[[], G]
|
|
||||||
def warn_if_empty(f: CC) -> CC:
|
def warn_if_empty(f: CC) -> CC:
|
||||||
@wraps(f)
|
from functools import wraps
|
||||||
def wrapped(*args, **kwargs) -> G[X]:
|
@wraps(f) # type: ignore[arg-type]
|
||||||
res = f(*args, **kwargs)
|
def wrapped(*args, **kwargs):
|
||||||
|
res = f(*args, **kwargs) # type: ignore[call-arg, operator]
|
||||||
return _warn_iterable(res)
|
return _warn_iterable(res)
|
||||||
return wrapped
|
return wrapped # type: ignore[return-value]
|
||||||
|
|
|
@ -53,20 +53,38 @@ from my.core.error import test_sort_res_by
|
||||||
from typing import Iterable, List
|
from typing import Iterable, List
|
||||||
import warnings
|
import warnings
|
||||||
from my.core import warn_if_empty
|
from my.core import warn_if_empty
|
||||||
def test_warn_if_empty():
|
def test_warn_if_empty() -> None:
|
||||||
|
|
||||||
@warn_if_empty
|
@warn_if_empty
|
||||||
def nonempty() -> Iterable[str]:
|
def nonempty() -> Iterable[str]:
|
||||||
yield 'a'
|
yield 'a'
|
||||||
yield 'aba'
|
yield 'aba'
|
||||||
|
|
||||||
@warn_if_empty
|
@warn_if_empty
|
||||||
def empty(arg: str) -> List[str]:
|
def empty() -> List[str]:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
assert list(nonempty()) == ['a', 'aba']
|
assert list(nonempty()) == ['a', 'aba']
|
||||||
assert len(w) == 0
|
assert len(w) == 0
|
||||||
|
|
||||||
assert empty('whatever') == []
|
eee = empty()
|
||||||
|
assert eee == []
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_warn_iterable() -> None:
|
||||||
|
from my.core.common import _warn_iterable
|
||||||
|
i1: List[str] = ['a', 'b']
|
||||||
|
i2: Iterable[int] = iter([1, 2, 3])
|
||||||
|
# reveal_type(i1)
|
||||||
|
# reveal_type(i2)
|
||||||
|
x1 = _warn_iterable(i1)
|
||||||
|
x2 = _warn_iterable(i2)
|
||||||
|
# reveal_type(x1)
|
||||||
|
# reveal_type(x2)
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
assert x1 is i1 # should be unchanged!
|
||||||
|
assert len(w) == 0
|
||||||
|
|
||||||
|
assert list(x2) == [1, 2, 3]
|
||||||
|
assert len(w) == 0
|
||||||
|
|
Loading…
Add table
Reference in a new issue