reflect cachew changes of exception handling and temporary suppression
This commit is contained in:
parent
d3f2551560
commit
ced93e6942
12 changed files with 29 additions and 46 deletions
|
@ -1,40 +1,29 @@
|
|||
# TODO this probably belongs to cachew? or cachew.experimental
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def disable_cachew():
|
||||
'''
|
||||
NOTE: you need to use it before importing any function using @cachew.cachew
|
||||
'''
|
||||
# TODO not sure... maybe it should instead use some hook.. it's a ibt ugly do
|
||||
try:
|
||||
import cachew
|
||||
except ImportError:
|
||||
# nothing to disable
|
||||
return
|
||||
|
||||
@cachew.doublewrap
|
||||
def cachew_off(func=None, *args, **kwargs):
|
||||
return func
|
||||
old = cachew.cachew
|
||||
cachew.cachew = cachew_off
|
||||
return old
|
||||
from cachew import settings
|
||||
settings.ENABLE = False
|
||||
|
||||
|
||||
@contextmanager
|
||||
def disabled_cachew():
|
||||
try:
|
||||
import cachew
|
||||
except ModuleNotFoundError:
|
||||
# no need to disable anything
|
||||
except ImportError:
|
||||
# nothing to disable
|
||||
yield
|
||||
return
|
||||
old = disable_cachew()
|
||||
try:
|
||||
from cachew.extra import disabled_cachew
|
||||
with disabled_cachew():
|
||||
yield
|
||||
finally:
|
||||
cachew.cachew = old
|
||||
|
||||
|
||||
def cache_dir() -> Path:
|
||||
|
|
|
@ -202,7 +202,7 @@ if TYPE_CHECKING:
|
|||
|
||||
mcachew: McachewType
|
||||
|
||||
# TODO ugh. I think it needs doublewrap, otherwise @mcachew without args doesn't work
|
||||
# todo ugh. I think it needs doublewrap, otherwise @mcachew without args doesn't work
|
||||
def mcachew(*args, **kwargs): # type: ignore[no-redef]
|
||||
"""
|
||||
Stands for 'Maybe cachew'.
|
||||
|
@ -214,8 +214,6 @@ def mcachew(*args, **kwargs): # type: ignore[no-redef]
|
|||
warnings.warn('cachew library not found. You might want to install it to speed things up. See https://github.com/karlicoss/cachew')
|
||||
return lambda orig_func: orig_func
|
||||
else:
|
||||
import cachew.experimental
|
||||
cachew.experimental.enable_exceptions() # TODO do it only once?
|
||||
return cachew.cachew(*args, **kwargs)
|
||||
|
||||
|
||||
|
|
|
@ -105,18 +105,20 @@ def test_sort_res_by() -> None:
|
|||
# todo proper typevar?
|
||||
from datetime import datetime
|
||||
def set_error_datetime(e: Exception, dt: datetime) -> None:
|
||||
# at the moment, we're using isoformat() instead of datetime directly to make it cachew-friendly
|
||||
# once cachew preserves exception argument types, we can remove these hacks
|
||||
e.args = e.args + (dt.isoformat(), )
|
||||
e.args = e.args + (dt,)
|
||||
# todo not sure if should return new exception?
|
||||
|
||||
|
||||
# todo it might be problematic because might mess with timezones (when it's converted to string, it's converted to a shift)
|
||||
def extract_error_datetime(e: Exception) -> Optional[datetime]:
|
||||
from .common import fromisoformat
|
||||
import re
|
||||
# TODO FIXME meh. definitely need to preserve exception args types in cachew if possible..
|
||||
for x in reversed(e.args):
|
||||
m = re.search(r'\d{4}-\d\d-\d\d(T..:..:..)?(\.\d{6})?(\+.....)?', x)
|
||||
if isinstance(x, datetime):
|
||||
return x
|
||||
if not isinstance(x, str):
|
||||
continue
|
||||
m = re.search(r'\d{4}-\d\d-\d\d(...:..:..)?(\.\d{6})?(\+.....)?', x)
|
||||
if m is None:
|
||||
continue
|
||||
ss = m.group(0)
|
||||
|
@ -134,8 +136,8 @@ def test_datetime_errors() -> None:
|
|||
assert extract_error_datetime(e1) is None
|
||||
set_error_datetime(e1, dt=dt)
|
||||
assert extract_error_datetime(e1) == dt
|
||||
# test that cachew can handle it...
|
||||
e2 = RuntimeError(str(e1.args))
|
||||
|
||||
e2 = RuntimeError(f'something something {dt} something else')
|
||||
assert extract_error_datetime(e2) == dt
|
||||
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ class Window:
|
|||
|
||||
|
||||
|
||||
# TODO cachew as well?
|
||||
# todo cachew as well?
|
||||
# TODO maybe if tag is none, we just don't care?
|
||||
def get_groups(*args, **kwargs) -> List[LocInterval]:
|
||||
all_locations = iter(iter_locations(*args, **kwargs))
|
||||
|
|
|
@ -140,8 +140,6 @@ def _candidates() -> Iterable[str]:
|
|||
def photos() -> Iterator[Result]:
|
||||
candidates = tuple(sorted(_candidates()))
|
||||
return _photos(candidates)
|
||||
# TODO figure out how to use cachew without helper function?
|
||||
# I guess need lazy variables or something?
|
||||
|
||||
|
||||
# if geo information is missing from photo, you can specify it manually in geo.json file
|
||||
|
@ -188,5 +186,5 @@ def print_all():
|
|||
else:
|
||||
print(f"{p.dt} {p.path} {p.tags}")
|
||||
|
||||
# TODO cachew -- improve AttributeError: type object 'tuple' has no attribute '__annotations__' -- improve errors?
|
||||
# TODO cachew -- invalidate if function code changed?
|
||||
# todo cachew -- improve AttributeError: type object 'tuple' has no attribute '__annotations__' -- improve errors?
|
||||
# todo cachew -- invalidate if function code changed?
|
||||
|
|
|
@ -155,7 +155,7 @@ def _get_state(bfile: Path) -> Dict[Sid, SaveWithDt]:
|
|||
# it's called early so it ends up as a global variable that we can't monkey patch easily
|
||||
@mcachew
|
||||
def _get_events(backups: Sequence[Path], parallel: bool=True) -> Iterator[Event]:
|
||||
# TODO cachew: let it transform return type? so you don't have to write a wrapper for lists?
|
||||
# todo cachew: let it transform return type? so you don't have to write a wrapper for lists?
|
||||
|
||||
prev_saves: Mapping[Sid, SaveWithDt] = {}
|
||||
# TODO suppress first batch??
|
||||
|
|
|
@ -73,8 +73,6 @@ from contextlib import contextmanager
|
|||
@contextmanager
|
||||
def fake_data(rows: int=1000) -> Iterator[None]:
|
||||
# todo also disable cachew automatically for such things?
|
||||
# TODO right, disabled_cachew won't work here because at that point, entries() is already wrapped?
|
||||
# I guess need to fix this in cachew?
|
||||
from .core.cachew import disabled_cachew
|
||||
from .core.cfg import override_config
|
||||
from tempfile import TemporaryDirectory
|
||||
|
|
2
setup.py
2
setup.py
|
@ -61,7 +61,7 @@ def main():
|
|||
'optional': [
|
||||
# TODO document these?
|
||||
'logzero',
|
||||
'cachew',
|
||||
'cachew>=0.8.0',
|
||||
'mypy', # used for config checks
|
||||
],
|
||||
':python_version<"3.7"': [
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
|
||||
from my.core.cachew import disable_cachew
|
||||
disable_cachew() # meh
|
||||
|
||||
|
||||
def test() -> None:
|
||||
from my.bluemaestro import measurements
|
||||
|
|
8
tests/conftest.py
Normal file
8
tests/conftest.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
import pytest # type: ignore
|
||||
|
||||
# I guess makes sense by default
|
||||
@pytest.fixture(autouse=True)
|
||||
def without_cachew():
|
||||
from my.core.cachew import disabled_cachew
|
||||
with disabled_cachew():
|
||||
yield
|
|
@ -1,7 +1,3 @@
|
|||
from my.core.cachew import disable_cachew
|
||||
# TODO need something nicer and integrated inside cachew..
|
||||
disable_cachew() # meh
|
||||
|
||||
from more_itertools import ilen
|
||||
|
||||
from my.lastfm import scrobbles
|
||||
|
|
|
@ -3,9 +3,6 @@ from datetime import datetime
|
|||
from itertools import islice
|
||||
import pytz
|
||||
|
||||
from my.core.cachew import disable_cachew
|
||||
disable_cachew()
|
||||
|
||||
import my.location.takeout as LT
|
||||
from my.google.takeout.html import read_html
|
||||
from my.google.takeout.paths import get_last_takeout
|
||||
|
|
Loading…
Add table
Reference in a new issue