general: move assert_never to my.core.compat as it's in stdlib from 3.11

rely on typing-extensions for fallback

introducing typing-extensions dependency without fallback, should be ok since it's in the top 10 of popular packages
This commit is contained in:
Dima Gerasimov 2024-08-12 15:45:59 +03:00 committed by karlicoss
parent 1317914bff
commit a7439c7846
10 changed files with 36 additions and 16 deletions

View file

@ -54,9 +54,10 @@ class Message(_BaseMessage):
import json import json
from typing import Union from typing import Union
from ..core import Res, assert_never from ..core import Res
import sqlite3 import sqlite3
from ..core.sqlite import sqlite_connect_immutable, select from ..core.sqlite import sqlite_connect_immutable, select
from my.core.compat import assert_never
EntitiesRes = Res[Union[Person, _Message]] EntitiesRes = Res[Union[Person, _Message]]

View file

@ -6,7 +6,6 @@ from pathlib import Path
from typing import Dict, Iterator, Sequence from typing import Dict, Iterator, Sequence
from my.core import get_files, Res, datetime_aware from my.core import get_files, Res, datetime_aware
from my.core.common import assert_never
from my.config import codeforces as config # type: ignore[attr-defined] from my.config import codeforces as config # type: ignore[attr-defined]
@ -73,7 +72,7 @@ class Parser:
# these contain only contests the user participated in # these contain only contests the user participated in
yield from self._parse_competitions(path) yield from self._parse_competitions(path)
else: else:
raise RuntimeError("shouldn't happen") # TODO switch to compat.assert_never raise RuntimeError(f"shouldn't happen: {path.name}")
def data() -> Iterator[Res[Competition]]: def data() -> Iterator[Res[Competition]]:

View file

@ -4,7 +4,7 @@ from .common import Json
from .common import warn_if_empty from .common import warn_if_empty
from .common import stat, Stats from .common import stat, Stats
from .common import datetime_naive, datetime_aware from .common import datetime_naive, datetime_aware
from .common import assert_never from .compat import assert_never
from .cfg import make_config from .cfg import make_config
from .error import Res, unwrap from .error import Res, unwrap
@ -26,7 +26,7 @@ __all__ = [
'warn_if_empty', 'warn_if_empty',
'stat', 'Stats', 'stat', 'Stats',
'datetime_aware', 'datetime_naive', 'datetime_aware', 'datetime_naive',
'assert_never', 'assert_never', # TODO maybe deprecate from use in my.core? will be in stdlib soon
'make_config', 'make_config',
@ -34,7 +34,7 @@ __all__ = [
'Res', 'unwrap', 'Res', 'unwrap',
'dataclass', 'Path', 'dataclass', 'Path', # TODO deprecate these from use in my.core
] ]

View file

@ -27,7 +27,10 @@ from typing import (
get_origin, get_origin,
) )
import warnings import warnings
from . import warnings as core_warnings from . import warnings as core_warnings
from . import compat
from .compat import deprecated
# some helper functions # some helper functions
PathIsh = Union[Path, str] PathIsh = Union[Path, str]
@ -633,11 +636,6 @@ class DummyExecutor(Executor):
self._shutdown = True self._shutdown = True
# see https://hakibenita.com/python-mypy-exhaustive-checking#exhaustiveness-checking
def assert_never(value: NoReturn) -> NoReturn:
assert False, f'Unhandled value: {value} ({type(value).__name__})'
def _check_all_hashable(fun): def _check_all_hashable(fun):
# TODO ok, take callable? # TODO ok, take callable?
hints = get_type_hints(fun) hints = get_type_hints(fun)
@ -693,6 +691,13 @@ def unique_everseen(
## 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
## 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
if not TYPE_CHECKING:
assert_never = deprecated('use my.core.compat.assert_never instead')(compat.assert_never)
# TODO wrap in deprecated decorator as well?
from functools import cached_property as cproperty from functools import cached_property as cproperty
from typing import Literal from typing import Literal
from .cachew import mcachew from .cachew import mcachew

View file

@ -121,3 +121,15 @@ if sys.version_info[:2] >= (3, 10):
from types import NoneType from types import NoneType
else: 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):
from typing import assert_never
else:
from typing_extensions import assert_never

View file

@ -9,7 +9,8 @@ from tempfile import TemporaryDirectory
from typing import Tuple, Any, Iterator, Callable, Optional, Union, Literal from typing import Tuple, Any, Iterator, Callable, Optional, Union, Literal
from .common import PathIsh, assert_never from .common import PathIsh
from .compat import assert_never
def sqlite_connect_immutable(db: PathIsh) -> sqlite3.Connection: def sqlite_connect_immutable(db: PathIsh) -> sqlite3.Connection:

View file

@ -1,8 +1,7 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Iterator, List, Tuple from typing import Any, Iterator, List, Tuple
from my.core import assert_never from my.core.compat import NoneType, assert_never
from my.core.compat import NoneType
# TODO Popper? not sure # TODO Popper? not sure

View file

@ -10,8 +10,9 @@ from pathlib import Path
import sqlite3 import sqlite3
from typing import Iterator, Sequence, Optional, Dict, Union, List from typing import Iterator, Sequence, Optional, Dict, Union, List
from my.core import get_files, Paths, datetime_aware, Res, assert_never, LazyLogger, make_config from my.core import get_files, Paths, datetime_aware, Res, LazyLogger, make_config
from my.core.common import unique_everseen from my.core.common import unique_everseen
from my.core.compat import assert_never
from my.core.error import echain from my.core.error import echain
from my.core.sqlite import sqlite_connection from my.core.sqlite import sqlite_connection

View file

@ -11,8 +11,9 @@ from pathlib import Path
import sqlite3 import sqlite3
from typing import Sequence, Iterator, Union, Dict, List, Mapping from typing import Sequence, Iterator, Union, Dict, List, Mapping
from my.core import Paths, get_files, Res, assert_never, stat, Stats, datetime_aware, make_logger from my.core import Paths, get_files, Res, stat, Stats, datetime_aware, make_logger
from my.core.common import unique_everseen from my.core.common import unique_everseen
from my.core.compat import assert_never
from my.core.error import echain from my.core.error import echain
from my.core.sqlite import sqlite_connection from my.core.sqlite import sqlite_connection
import my.config import my.config

View file

@ -5,6 +5,7 @@ from setuptools import setup, find_namespace_packages # type: ignore
INSTALL_REQUIRES = [ INSTALL_REQUIRES = [
'pytz', # even though it's not needed by the core, it's so common anyway... 'pytz', # even though it's not needed by the core, it's so common anyway...
'typing-extensions', # one of the most common pypi packages, ok to depend for core
'appdirs', # very common, and makes it portable 'appdirs', # very common, and makes it portable
'more-itertools', # it's just too useful and very common anyway 'more-itertools', # it's just too useful and very common anyway
'decorator' , # less pain in writing correct decorators. very mature and stable, so worth keeping in core 'decorator' , # less pain in writing correct decorators. very mature and stable, so worth keeping in core