core: cleanup deprecations, exclude from type checking and show runtime warnings
among affected things: - core.common.assert_never - core.common.cproperty - core.common.isoparse - core.common.mcachew - core.common.the - core.common.tzdatetime - core.compat.sqlite_backup
This commit is contained in:
parent
a7439c7846
commit
973c4205df
24 changed files with 118 additions and 103 deletions
|
@ -21,7 +21,7 @@ from my.core import (
|
||||||
Stats,
|
Stats,
|
||||||
influxdb,
|
influxdb,
|
||||||
)
|
)
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import mcachew
|
||||||
from my.core.error import unwrap
|
from my.core.error import unwrap
|
||||||
from my.core.pandas import DataFrameT, as_dataframe
|
from my.core.pandas import DataFrameT, as_dataframe
|
||||||
from my.core.sqlite import sqlite_connect_immutable
|
from my.core.sqlite import sqlite_connect_immutable
|
||||||
|
|
|
@ -16,7 +16,7 @@ from my.core import (
|
||||||
make_logger,
|
make_logger,
|
||||||
stat,
|
stat,
|
||||||
)
|
)
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import mcachew
|
||||||
|
|
||||||
from browserexport.merge import read_and_merge, Visit
|
from browserexport.merge import read_and_merge, Visit
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,7 @@ from typing import List, Optional, Iterator, Set, Sequence, cast
|
||||||
|
|
||||||
|
|
||||||
from my.core import PathIsh, LazyLogger, make_config
|
from my.core import PathIsh, LazyLogger, make_config
|
||||||
from my.core.cachew import cache_dir
|
from my.core.cachew import cache_dir, mcachew
|
||||||
from my.core.common import mcachew
|
|
||||||
from my.core.warnings import high
|
from my.core.warnings import high
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ from typing import (
|
||||||
Iterable,
|
Iterable,
|
||||||
Iterator,
|
Iterator,
|
||||||
List,
|
List,
|
||||||
NoReturn,
|
|
||||||
Optional,
|
Optional,
|
||||||
Sequence,
|
Sequence,
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
|
@ -70,17 +69,6 @@ T = TypeVar('T')
|
||||||
K = TypeVar('K')
|
K = TypeVar('K')
|
||||||
V = TypeVar('V')
|
V = TypeVar('V')
|
||||||
|
|
||||||
# TODO deprecate? more_itertools.one should be used
|
|
||||||
def the(l: Iterable[T]) -> T:
|
|
||||||
it = iter(l)
|
|
||||||
try:
|
|
||||||
first = next(it)
|
|
||||||
except StopIteration:
|
|
||||||
raise RuntimeError('Empty iterator?')
|
|
||||||
assert all(e == first for e in it)
|
|
||||||
return first
|
|
||||||
|
|
||||||
|
|
||||||
# TODO more_itertools.bucket?
|
# TODO more_itertools.bucket?
|
||||||
def group_by_key(l: Iterable[T], key: Callable[[T], K]) -> Dict[K, List[T]]:
|
def group_by_key(l: Iterable[T], key: Callable[[T], K]) -> Dict[K, List[T]]:
|
||||||
res: Dict[K, List[T]] = {}
|
res: Dict[K, List[T]] = {}
|
||||||
|
@ -322,14 +310,6 @@ datetime_naive = datetime
|
||||||
datetime_aware = datetime
|
datetime_aware = datetime
|
||||||
|
|
||||||
|
|
||||||
# TODO deprecate
|
|
||||||
tzdatetime = datetime_aware
|
|
||||||
|
|
||||||
|
|
||||||
# TODO deprecate (although could be used in modules)
|
|
||||||
from .compat import fromisoformat as isoparse
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
# https://stackoverflow.com/a/295466/706389
|
# https://stackoverflow.com/a/295466/706389
|
||||||
def get_valid_filename(s: str) -> str:
|
def get_valid_filename(s: str) -> str:
|
||||||
|
@ -554,7 +534,7 @@ def test_guess_datetime() -> None:
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
dd = isoparse('2021-02-01T12:34:56Z')
|
dd = compat.fromisoformat('2021-02-01T12:34:56Z')
|
||||||
|
|
||||||
# ugh.. https://github.com/python/mypy/issues/7281
|
# ugh.. https://github.com/python/mypy/issues/7281
|
||||||
A = NamedTuple('A', [('x', int)])
|
A = NamedTuple('A', [('x', int)])
|
||||||
|
@ -690,15 +670,41 @@ def unique_everseen(
|
||||||
return more_itertools.unique_everseen(iterable=iterable, key=key)
|
return more_itertools.unique_everseen(iterable=iterable, key=key)
|
||||||
|
|
||||||
|
|
||||||
## legacy imports, keeping them here for backwards compatibility
|
### legacy imports, keeping them here for backwards compatibility
|
||||||
## hiding behind TYPE_CHECKING so it works in runtime
|
## hiding behind TYPE_CHECKING so it works in runtime
|
||||||
## in principle, warnings.deprecated decorator should cooperate with mypy, but doesn't look like it works atm?
|
## in principle, warnings.deprecated decorator should cooperate with mypy, but doesn't look like it works atm?
|
||||||
## perhaps it doesn't work when it's used from typing_extensions
|
## perhaps it doesn't work when it's used from typing_extensions
|
||||||
if not TYPE_CHECKING:
|
if not TYPE_CHECKING:
|
||||||
assert_never = deprecated('use my.core.compat.assert_never instead')(compat.assert_never)
|
|
||||||
|
|
||||||
# TODO wrap in deprecated decorator as well?
|
@deprecated('use my.core.compat.assert_never instead')
|
||||||
from functools import cached_property as cproperty
|
def assert_never(*args, **kwargs):
|
||||||
from typing import Literal
|
return compat.assert_never(*args, **kwargs)
|
||||||
from .cachew import mcachew
|
|
||||||
##
|
@deprecated('use my.core.compat.fromisoformat instead')
|
||||||
|
def isoparse(*args, **kwargs):
|
||||||
|
return compat.fromisoformat(*args, **kwargs)
|
||||||
|
|
||||||
|
@deprecated('use more_itertools.one instead')
|
||||||
|
def the(*args, **kwargs):
|
||||||
|
import more_itertools
|
||||||
|
|
||||||
|
return more_itertools.one(*args, **kwargs)
|
||||||
|
|
||||||
|
@deprecated('use functools.cached_property instead')
|
||||||
|
def cproperty(*args, **kwargs):
|
||||||
|
import functools
|
||||||
|
|
||||||
|
return functools.cached_property(*args, **kwargs)
|
||||||
|
|
||||||
|
# todo wrap these in deprecated decorator as well?
|
||||||
|
from .cachew import mcachew # noqa: F401
|
||||||
|
|
||||||
|
from typing import Literal # noqa: F401
|
||||||
|
|
||||||
|
# TODO hmm how to deprecate it in runtime? tricky cause it's actually a class?
|
||||||
|
tzdatetime = datetime_aware
|
||||||
|
else:
|
||||||
|
from .compat import Never
|
||||||
|
|
||||||
|
tzdatetime = Never # makes it invalid as a type while working in runtime
|
||||||
|
###
|
||||||
|
|
|
@ -2,17 +2,24 @@
|
||||||
Contains backwards compatibility helpers for different python versions.
|
Contains backwards compatibility helpers for different python versions.
|
||||||
If something is relevant to HPI itself, please put it in .hpi_compat instead
|
If something is relevant to HPI itself, please put it in .hpi_compat instead
|
||||||
'''
|
'''
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
|
||||||
windows = os.name == 'nt'
|
if sys.version_info[:2] >= (3, 13):
|
||||||
|
from warnings import deprecated
|
||||||
|
else:
|
||||||
|
from typing_extensions import deprecated
|
||||||
|
|
||||||
|
|
||||||
# keeping just for backwards compatibility, used to have compat implementation for 3.6
|
# keeping just for backwards compatibility, used to have compat implementation for 3.6
|
||||||
|
if not TYPE_CHECKING:
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
|
@deprecated('use .backup method on sqlite3.Connection directly instead')
|
||||||
def sqlite_backup(*, source: sqlite3.Connection, dest: sqlite3.Connection, **kwargs) -> None:
|
def sqlite_backup(*, source: sqlite3.Connection, dest: sqlite3.Connection, **kwargs) -> None:
|
||||||
|
# TODO warn here?
|
||||||
source.backup(dest, **kwargs)
|
source.backup(dest, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,35 +30,30 @@ def removeprefix(text: str, prefix: str) -> str:
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
## used to have compat function before 3.8 for these
|
## used to have compat function before 3.8 for these, keeping for runtime back compatibility
|
||||||
|
if not TYPE_CHECKING:
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from typing import Literal, Protocol, TypedDict
|
from typing import Literal, Protocol, TypedDict
|
||||||
|
else:
|
||||||
|
from typing_extensions import Literal, Protocol, TypedDict
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 10):
|
if sys.version_info[:2] >= (3, 10):
|
||||||
from typing import ParamSpec
|
from typing import ParamSpec
|
||||||
else:
|
else:
|
||||||
if TYPE_CHECKING:
|
|
||||||
from typing_extensions import ParamSpec
|
from typing_extensions import ParamSpec
|
||||||
else:
|
|
||||||
from typing import NamedTuple, Any
|
|
||||||
# erm.. I guess as long as it's not crashing, whatever...
|
|
||||||
class _ParamSpec:
|
|
||||||
def __call__(self, args):
|
|
||||||
class _res:
|
|
||||||
args = None
|
|
||||||
kwargs = None
|
|
||||||
return _res
|
|
||||||
ParamSpec = _ParamSpec()
|
|
||||||
|
|
||||||
|
|
||||||
# bisect_left doesn't have a 'key' parameter (which we use)
|
# bisect_left doesn't have a 'key' parameter (which we use)
|
||||||
# till python3.10
|
# till python3.10
|
||||||
if sys.version_info[:2] <= (3, 9):
|
if sys.version_info[:2] <= (3, 9):
|
||||||
from typing import List, TypeVar, Any, Optional, Callable
|
from typing import List, TypeVar, Any, Optional, Callable
|
||||||
|
|
||||||
X = TypeVar('X')
|
X = TypeVar('X')
|
||||||
|
|
||||||
# copied from python src
|
# copied from python src
|
||||||
|
# fmt: off
|
||||||
def bisect_left(a: List[Any], x: Any, lo: int=0, hi: Optional[int]=None, *, key: Optional[Callable[..., Any]]=None) -> int:
|
def bisect_left(a: List[Any], x: Any, lo: int=0, hi: Optional[int]=None, *, key: Optional[Callable[..., Any]]=None) -> int:
|
||||||
if lo < 0:
|
if lo < 0:
|
||||||
raise ValueError('lo must be non-negative')
|
raise ValueError('lo must be non-negative')
|
||||||
|
@ -74,19 +76,22 @@ if sys.version_info[:2] <= (3, 9):
|
||||||
else:
|
else:
|
||||||
hi = mid
|
hi = mid
|
||||||
return lo
|
return lo
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
else:
|
else:
|
||||||
from bisect import bisect_left
|
from bisect import bisect_left
|
||||||
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 11):
|
if sys.version_info[:2] >= (3, 11):
|
||||||
fromisoformat = datetime.fromisoformat
|
fromisoformat = datetime.fromisoformat
|
||||||
else:
|
else:
|
||||||
def fromisoformat(date_string: str) -> datetime:
|
# fromisoformat didn't support Z as "utc" before 3.11
|
||||||
# didn't support Z as "utc" before 3.11
|
|
||||||
if date_string.endswith('Z'):
|
|
||||||
# NOTE: can be removed from 3.11?
|
|
||||||
# https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat
|
# https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat
|
||||||
|
|
||||||
|
def fromisoformat(date_string: str) -> datetime:
|
||||||
|
if date_string.endswith('Z'):
|
||||||
date_string = date_string[:-1] + '+00:00'
|
date_string = date_string[:-1] + '+00:00'
|
||||||
return datetime.fromisoformat(date_string)
|
return datetime.fromisoformat(date_string)
|
||||||
|
|
||||||
|
@ -94,6 +99,7 @@ else:
|
||||||
def test_fromisoformat() -> None:
|
def test_fromisoformat() -> None:
|
||||||
from datetime import timezone
|
from datetime import timezone
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
# feedbin has this format
|
# feedbin has this format
|
||||||
assert fromisoformat('2020-05-01T10:32:02.925961Z') == datetime(
|
assert fromisoformat('2020-05-01T10:32:02.925961Z') == datetime(
|
||||||
2020, 5, 1, 10, 32, 2, 925961, timezone.utc,
|
2020, 5, 1, 10, 32, 2, 925961, timezone.utc,
|
||||||
|
@ -108,6 +114,7 @@ def test_fromisoformat() -> None:
|
||||||
assert fromisoformat('2020-11-30T00:53:12Z') == datetime(
|
assert fromisoformat('2020-11-30T00:53:12Z') == datetime(
|
||||||
2020, 11, 30, 0, 53, 12, 0, timezone.utc,
|
2020, 11, 30, 0, 53, 12, 0, timezone.utc,
|
||||||
)
|
)
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
# arbtt has this format (sometimes less/more than 6 digits in milliseconds)
|
# arbtt has this format (sometimes less/more than 6 digits in milliseconds)
|
||||||
# TODO doesn't work atm, not sure if really should be supported...
|
# TODO doesn't work atm, not sure if really should be supported...
|
||||||
|
@ -123,13 +130,13 @@ else:
|
||||||
NoneType = type(None)
|
NoneType = type(None)
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 13):
|
|
||||||
from warnings import deprecated
|
|
||||||
else:
|
|
||||||
from typing_extensions import deprecated
|
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 11):
|
if sys.version_info[:2] >= (3, 11):
|
||||||
from typing import assert_never
|
from typing import assert_never
|
||||||
else:
|
else:
|
||||||
from typing_extensions import assert_never
|
from typing_extensions import assert_never
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info[:2] >= (3, 11):
|
||||||
|
from typing import Never
|
||||||
|
else:
|
||||||
|
from typing_extensions import Never
|
||||||
|
|
|
@ -10,7 +10,7 @@ def test_cachew() -> None:
|
||||||
|
|
||||||
settings.ENABLE = True # by default it's off in tests (see conftest.py)
|
settings.ENABLE = True # by default it's off in tests (see conftest.py)
|
||||||
|
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import mcachew
|
||||||
|
|
||||||
called = 0
|
called = 0
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ def test_cachew_dir_none() -> None:
|
||||||
settings.ENABLE = True # by default it's off in tests (see conftest.py)
|
settings.ENABLE = True # by default it's off in tests (see conftest.py)
|
||||||
|
|
||||||
from my.core.cachew import cache_dir
|
from my.core.cachew import cache_dir
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import mcachew
|
||||||
from my.core.core_config import _reset_config as reset
|
from my.core.core_config import _reset_config as reset
|
||||||
|
|
||||||
with reset() as cc:
|
with reset() as cc:
|
||||||
|
|
|
@ -6,7 +6,6 @@ from typing import TYPE_CHECKING
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
from ..common import get_files
|
from ..common import get_files
|
||||||
from ..compat import windows
|
|
||||||
from ..kompress import CPath, ZipPath
|
from ..kompress import CPath, ZipPath
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -56,8 +55,9 @@ def test_single_file() -> None:
|
||||||
'''
|
'''
|
||||||
assert get_files('/tmp/hpi_test/file.ext') == (Path('/tmp/hpi_test/file.ext'),)
|
assert get_files('/tmp/hpi_test/file.ext') == (Path('/tmp/hpi_test/file.ext'),)
|
||||||
|
|
||||||
|
is_windows = os.name == 'nt'
|
||||||
"if the path starts with ~, we expand it"
|
"if the path starts with ~, we expand it"
|
||||||
if not windows: # windows doesn't have bashrc.. ugh
|
if not is_windows: # windows doesn't have bashrc.. ugh
|
||||||
assert get_files('~/.bashrc') == (Path('~').expanduser() / '.bashrc',)
|
assert get_files('~/.bashrc') == (Path('~').expanduser() / '.bashrc',)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ from my.core import (
|
||||||
Res,
|
Res,
|
||||||
Stats,
|
Stats,
|
||||||
)
|
)
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import cache_dir, mcachew
|
||||||
from my.core.cachew import cache_dir
|
|
||||||
from my.core.error import set_error_datetime, extract_error_datetime
|
from my.core.error import set_error_datetime, extract_error_datetime
|
||||||
from my.core.pandas import DataFrameT
|
from my.core.pandas import DataFrameT
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,11 @@ except ModuleNotFoundError as e:
|
||||||
############################
|
############################
|
||||||
|
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
from pathlib import Path
|
||||||
from typing import Tuple, Dict, Sequence, Optional
|
from typing import Tuple, Dict, Sequence, Optional
|
||||||
|
|
||||||
from my.core import get_files, Path, LazyLogger
|
from my.core import get_files, LazyLogger
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import mcachew
|
||||||
|
|
||||||
from .common import Event, parse_dt, Results, EventIds
|
from .common import Event, parse_dt, Results, EventIds
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ import os
|
||||||
from typing import List, Sequence, cast
|
from typing import List, Sequence, cast
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from my.core import make_config, dataclass
|
from my.core import make_config, dataclass
|
||||||
from my.core.common import Stats, LazyLogger, mcachew, get_files, Paths
|
from my.core.cachew import mcachew
|
||||||
|
from my.core.common import Stats, LazyLogger, get_files, Paths
|
||||||
from my.core.error import ErrorPolicy
|
from my.core.error import ErrorPolicy
|
||||||
from my.core.structure import match_structure
|
from my.core.structure import match_structure
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import NamedTuple, Sequence, Iterable
|
from typing import NamedTuple, Sequence, Iterable
|
||||||
|
|
||||||
from my.core.common import mcachew, Json, get_files
|
from my.core.cachew import mcachew
|
||||||
|
from my.core.common import Json, get_files
|
||||||
|
|
||||||
|
|
||||||
def inputs() -> Sequence[Path]:
|
def inputs() -> Sequence[Path]:
|
||||||
|
|
|
@ -19,8 +19,8 @@ import re
|
||||||
# pip3 install geopy
|
# pip3 install geopy
|
||||||
import geopy # type: ignore
|
import geopy # type: ignore
|
||||||
|
|
||||||
from ..core.common import LazyLogger, mcachew
|
from my.core.common import LazyLogger
|
||||||
from ..core.cachew import cache_dir
|
from my.core.cachew import cache_dir, mcachew
|
||||||
|
|
||||||
from my.core.warnings import high
|
from my.core.warnings import high
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ from typing import Iterator
|
||||||
from my.google.takeout.parser import events, _cachew_depends_on
|
from my.google.takeout.parser import events, _cachew_depends_on
|
||||||
from google_takeout_parser.models import Location as GoogleLocation
|
from google_takeout_parser.models import Location as GoogleLocation
|
||||||
|
|
||||||
from my.core.common import mcachew, LazyLogger, Stats
|
from my.core.cachew import mcachew
|
||||||
|
from my.core.common import LazyLogger, stat, Stats
|
||||||
from .common import Location
|
from .common import Location
|
||||||
|
|
||||||
logger = LazyLogger(__name__)
|
logger = LazyLogger(__name__)
|
||||||
|
@ -33,6 +34,4 @@ def locations() -> Iterator[Location]:
|
||||||
|
|
||||||
|
|
||||||
def stats() -> Stats:
|
def stats() -> Stats:
|
||||||
from my.core import stat
|
return stat(locations)
|
||||||
|
|
||||||
return {**stat(locations)}
|
|
||||||
|
|
|
@ -13,7 +13,8 @@ from my.google.takeout.parser import events, _cachew_depends_on as _parser_cache
|
||||||
from google_takeout_parser.models import PlaceVisit as SemanticLocation
|
from google_takeout_parser.models import PlaceVisit as SemanticLocation
|
||||||
|
|
||||||
from my.core import dataclass, make_config
|
from my.core import dataclass, make_config
|
||||||
from my.core.common import mcachew, LazyLogger, Stats
|
from my.core.cachew import mcachew
|
||||||
|
from my.core.common import LazyLogger, Stats, stat
|
||||||
from my.core.error import Res
|
from my.core.error import Res
|
||||||
from .common import Location
|
from .common import Location
|
||||||
|
|
||||||
|
@ -72,6 +73,4 @@ def locations() -> Iterator[Res[Location]]:
|
||||||
|
|
||||||
|
|
||||||
def stats() -> Stats:
|
def stats() -> Stats:
|
||||||
from my.core import stat
|
return stat(locations)
|
||||||
|
|
||||||
return {**stat(locations)}
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ from gpxpy.gpx import GPXXMLSyntaxException
|
||||||
from more_itertools import unique_everseen
|
from more_itertools import unique_everseen
|
||||||
|
|
||||||
from my.core import Stats, LazyLogger
|
from my.core import Stats, LazyLogger
|
||||||
from my.core.common import get_files, mcachew
|
from my.core.cachew import mcachew
|
||||||
|
from my.core.common import get_files
|
||||||
from .common import Location
|
from .common import Location
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,7 @@ import re
|
||||||
from typing import List, Sequence, Iterable, NamedTuple, Optional, Tuple
|
from typing import List, Sequence, Iterable, NamedTuple, Optional, Tuple
|
||||||
|
|
||||||
from my.core import get_files
|
from my.core import get_files
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import cache_dir, mcachew
|
||||||
from my.core.cachew import cache_dir
|
|
||||||
from my.core.orgmode import collect
|
from my.core.orgmode import collect
|
||||||
|
|
||||||
from my.config import orgmode as user_config
|
from my.config import orgmode as user_config
|
||||||
|
|
|
@ -15,8 +15,9 @@ from typing import NamedTuple, List, Optional, Iterator, Sequence
|
||||||
|
|
||||||
|
|
||||||
from my.core import LazyLogger, get_files, Paths, PathIsh
|
from my.core import LazyLogger, get_files, Paths, PathIsh
|
||||||
|
from my.core.cachew import mcachew
|
||||||
from my.core.cfg import Attrs, make_config
|
from my.core.cfg import Attrs, make_config
|
||||||
from my.core.common import mcachew, group_by_key
|
from my.core.common import group_by_key
|
||||||
from my.core.error import Res, split_errors
|
from my.core.error import Res, split_errors
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ from typing import Optional, NamedTuple, Iterator, Iterable, List
|
||||||
|
|
||||||
from geopy.geocoders import Nominatim # type: ignore
|
from geopy.geocoders import Nominatim # type: ignore
|
||||||
|
|
||||||
from ..core.common import LazyLogger, mcachew, fastermime
|
from my.core.common import LazyLogger, fastermime
|
||||||
from ..core.error import Res, sort_res_by
|
from my.core.error import Res, sort_res_by
|
||||||
from ..core.cachew import cache_dir
|
from my.core.cachew import cache_dir, mcachew
|
||||||
|
|
||||||
from my.config import photos as config # type: ignore[attr-defined]
|
from my.config import photos as config # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ from my.core import (
|
||||||
Paths,
|
Paths,
|
||||||
Stats,
|
Stats,
|
||||||
)
|
)
|
||||||
|
from my.core.cachew import mcachew
|
||||||
from my.core.cfg import make_config, Attrs
|
from my.core.cfg import make_config, Attrs
|
||||||
from my.core.common import mcachew
|
|
||||||
|
|
||||||
from my.config import reddit as uconfig
|
from my.config import reddit as uconfig
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from datetime import timedelta
|
||||||
from typing import Sequence, Iterable
|
from typing import Sequence, Iterable
|
||||||
|
|
||||||
from my.core import get_files, make_logger
|
from my.core import get_files, make_logger
|
||||||
from my.core.common import mcachew
|
from my.core.cachew import mcachew
|
||||||
from my.core.error import Res, split_errors
|
from my.core.error import Res, split_errors
|
||||||
|
|
||||||
from my.config import rescuetime as config
|
from my.config import rescuetime as config
|
||||||
|
|
|
@ -7,8 +7,8 @@ from my.config import feedbin as config
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from ..core.common import listify, get_files
|
from my.core.common import listify, get_files
|
||||||
from ..core.compat import fromisoformat
|
from my.core.compat import fromisoformat
|
||||||
from .common import Subscription
|
from .common import Subscription
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,12 +33,10 @@ def parse_file(f: Path):
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from .common import SubscriptionState
|
from .common import SubscriptionState
|
||||||
def states() -> Iterable[SubscriptionState]:
|
def states() -> Iterable[SubscriptionState]:
|
||||||
# meh
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
for f in inputs():
|
for f in inputs():
|
||||||
# TODO ugh. depends on my naming. not sure if useful?
|
# TODO ugh. depends on my naming. not sure if useful?
|
||||||
dts = f.stem.split('_')[-1]
|
dts = f.stem.split('_')[-1]
|
||||||
dt = isoparse(dts)
|
dt = fromisoformat(dts)
|
||||||
subs = parse_file(f)
|
subs = parse_file(f)
|
||||||
yield dt, subs
|
yield dt, subs
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Callable, cast
|
from typing import Callable, Literal, cast
|
||||||
|
|
||||||
from ...core.common import tzdatetime, Literal
|
from my.core.common import datetime_aware
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -30,7 +30,11 @@ def default_policy() -> TzPolicy:
|
||||||
return 'keep'
|
return 'keep'
|
||||||
|
|
||||||
|
|
||||||
def localize_with_policy(lfun: Callable[[datetime], tzdatetime], dt: datetime, policy: TzPolicy=default_policy()) -> tzdatetime:
|
def localize_with_policy(
|
||||||
|
lfun: Callable[[datetime], datetime_aware],
|
||||||
|
dt: datetime,
|
||||||
|
policy: TzPolicy=default_policy()
|
||||||
|
) -> datetime_aware:
|
||||||
tz = dt.tzinfo
|
tz = dt.tzinfo
|
||||||
if tz is None:
|
if tz is None:
|
||||||
return lfun(dt)
|
return lfun(dt)
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
Timezone data provider, used to localize timezone-unaware timestamps for other modules
|
Timezone data provider, used to localize timezone-unaware timestamps for other modules
|
||||||
'''
|
'''
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ...core.common import tzdatetime
|
from my.core.common import datetime_aware
|
||||||
|
|
||||||
# todo hmm, kwargs isn't mypy friendly.. but specifying types would require duplicating default args. uhoh
|
# todo hmm, kwargs isn't mypy friendly.. but specifying types would require duplicating default args. uhoh
|
||||||
def localize(dt: datetime, **kwargs) -> tzdatetime:
|
def localize(dt: datetime, **kwargs) -> datetime_aware:
|
||||||
# todo document patterns for combining multiple data sources
|
# todo document patterns for combining multiple data sources
|
||||||
# e.g. see https://github.com/karlicoss/HPI/issues/89#issuecomment-716495136
|
# e.g. see https://github.com/karlicoss/HPI/issues/89#issuecomment-716495136
|
||||||
from . import via_location as L
|
from . import via_location as L
|
||||||
|
|
|
@ -17,8 +17,8 @@ from typing import Iterator, Optional, Tuple, Any, List, Iterable, Set, Dict
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
|
from my.core.cachew import mcachew
|
||||||
from my.core import make_logger, stat, Stats, datetime_aware
|
from my.core import make_logger, stat, Stats, datetime_aware
|
||||||
from my.core.common import mcachew
|
|
||||||
from my.core.source import import_source
|
from my.core.source import import_source
|
||||||
from my.core.warnings import high
|
from my.core.warnings import high
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue