Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,5 @@ omit = [
exclude_also = [
"if TYPE_CHECKING:",
"^\\s*def .+: [.]{3}$", # def foo(): ... (... instead of pass)
"^\\s*assert_never\\(.*\\)$", # unreachable assertion, expected to not execute
]
17 changes: 16 additions & 1 deletion src/denokv/_pycompat/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dataclasses import dataclass
from dataclasses import fields as dataclass_fields
from typing import Literal
from typing import TypedDict
from typing import TypedDict # avoid circular reference with _pycompat.typing


class NoArg(TypedDict):
Expand All @@ -27,6 +27,21 @@ def slots_if310() -> SlotsTrue:
return SlotsTrue(slots=True)


class KwOnly(TypedDict):
kw_only: Literal[True]


if sys.version_info < (3, 10):

def kw_only_if310() -> NoArg:
return NoArg()

else:

def kw_only_if310() -> KwOnly:
return KwOnly(kw_only=True)


@dataclass
class FrozenAfterInitDataclass:
"""A mixin for dataclasses that disallows changing fields after init.
Expand Down
6 changes: 2 additions & 4 deletions src/denokv/_pycompat/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
from enum import EnumMeta
from enum import Flag
from enum import IntFlag
from typing import TYPE_CHECKING
from typing import Iterator

if TYPE_CHECKING:
from typing_extensions import Self
from denokv._pycompat.typing import Iterator
from denokv._pycompat.typing import Self


class ContainsValueEnumMeta(EnumMeta):
Expand Down
178 changes: 177 additions & 1 deletion src/denokv/_pycompat/typing.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,184 @@
from typing import TYPE_CHECKING
"""
Runtime comparability for typing things that come from typing_extensions.

We import all type annotations/types/functions from here, rather than typing or
typing_extensions in order to handle the differences between them in one place,
without needing if TYPE_CHECKING everywhere.
"""

from __future__ import annotations

from dataclasses import dataclass
from dataclasses import field
from typing import IO as IO
from typing import TYPE_CHECKING as TYPE_CHECKING

# Everything that exist in typing >=py39 except:
# - ByteString (deprecated)
# - overload (ruff does not recognise it when re-exported)
# - Literal (ruff does not recognise it when re-exported)
# - Handled below due to runtime differences:
# - TypeVar
from typing import AbstractSet as AbstractSet
from typing import Annotated as Annotated
from typing import Any as Any
from typing import AnyStr as AnyStr
from typing import AsyncContextManager as AsyncContextManager
from typing import AsyncGenerator as AsyncGenerator
from typing import AsyncIterable as AsyncIterable
from typing import AsyncIterator as AsyncIterator
from typing import Awaitable as Awaitable
from typing import BinaryIO as BinaryIO
from typing import Callable as Callable
from typing import ChainMap as ChainMap
from typing import ClassVar as ClassVar
from typing import Collection as Collection
from typing import Container as Container
from typing import ContextManager as ContextManager
from typing import Coroutine as Coroutine
from typing import Counter as Counter
from typing import DefaultDict as DefaultDict
from typing import Deque as Deque
from typing import Dict as Dict
from typing import Final as Final
from typing import ForwardRef as ForwardRef
from typing import FrozenSet as FrozenSet
from typing import Generator as Generator
from typing import Generic as Generic
from typing import Hashable as Hashable
from typing import ItemsView as ItemsView
from typing import Iterable as Iterable
from typing import Iterator as Iterator
from typing import KeysView as KeysView
from typing import List as List
from typing import Mapping as Mapping
from typing import MappingView as MappingView
from typing import Match as Match
from typing import MutableMapping as MutableMapping
from typing import MutableSequence as MutableSequence
from typing import MutableSet as MutableSet
from typing import NamedTuple as NamedTuple
from typing import NewType as NewType
from typing import NoReturn as NoReturn
from typing import Optional as Optional
from typing import OrderedDict as OrderedDict
from typing import Pattern as Pattern
from typing import Protocol as Protocol
from typing import Reversible as Reversible
from typing import Sequence as Sequence
from typing import Set as Set
from typing import Sized as Sized
from typing import SupportsAbs as SupportsAbs
from typing import SupportsBytes as SupportsBytes
from typing import SupportsComplex as SupportsComplex
from typing import SupportsFloat as SupportsFloat
from typing import SupportsIndex as SupportsIndex
from typing import SupportsInt as SupportsInt
from typing import SupportsRound as SupportsRound
from typing import Text as Text
from typing import TextIO as TextIO
from typing import Tuple as Tuple
from typing import Type as Type
from typing import TypedDict as TypedDict
from typing import Union as Union
from typing import ValuesView as ValuesView
from typing import cast as cast
from typing import final as final
from typing import get_args as get_args
from typing import get_origin as get_origin
from typing import get_type_hints as get_type_hints
from typing import no_type_check as no_type_check
from typing import no_type_check_decorator as no_type_check_decorator
from typing import runtime_checkable as runtime_checkable

if TYPE_CHECKING:
from typing_extensions import Never as Never
from typing_extensions import Self as Self
from typing_extensions import TypeAlias as TypeAlias
from typing_extensions import TypeGuard as TypeGuard
from typing_extensions import TypeIs as TypeIs
from typing_extensions import TypeVarTuple as TypeVarTuple
from typing_extensions import Unpack as Unpack
else:
Never = "Never"
ParamSpec = "ParamSpec"
Self = "Self"
TypeAlias = "TypeAlias"
TypeGuard = "TypeGuard"
TypeIs = "TypeIs"
# TypeVarTuple = "TypeVarTuple"
# Unpack = "Unpack"

if TYPE_CHECKING:
from typing_extensions import TypeVar as TypeVar
else:
from typing import TypeVar as _TypeVar

def TypeVar(
name: str,
*constraints: Any,
bound: Any | None = None,
covariant: bool = False,
contravariant: bool = False,
default: Any = ...,
infer_variance: bool = False,
) -> TypeVar:
return _TypeVar(
name, *constraints, covariant=covariant, contravariant=contravariant
)


_T = TypeVar("_T")

if TYPE_CHECKING:
from typing_extensions import TypeVarTuple as TypeVarTuple
else:

@dataclass
class TypeVarTuple:
name: str
default: Any = field(default=None)


if TYPE_CHECKING:
from typing_extensions import ParamSpec as ParamSpec
else:
from denokv._pycompat.dataclasses import kw_only_if310

@dataclass
class ParamSpec:
name: str
bound: type[Any] | str | None = field(default=None, **kw_only_if310())
contravariant: bool = field(default=False, **kw_only_if310())
covariant: bool = field(default=False, **kw_only_if310())
default: Any = field(default=None, **kw_only_if310())


if TYPE_CHECKING:
from typing_extensions import Unpack as Unpack
else:

@dataclass
class Unpack(Generic[_T]):
pass


if TYPE_CHECKING:
from typing_extensions import override as override
else:

def override(method, /):
return method


def assert_never(value: Never, /) -> Never:
"""Assert to the type checker that a line of code is unreachable."""
raise AssertionError(f"Expected code to be unreachable, but got: {value!r}")


if TYPE_CHECKING:
from typing_extensions import assert_type as assert_type
else:

def assert_type(val: _T, typ: Any, /) -> _T:
pass
6 changes: 3 additions & 3 deletions src/denokv/_rfc3339.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from typing import Final
from typing import TypedDict
from typing import cast

from denokv._pycompat.typing import Final
from denokv._pycompat.typing import TypedDict
from denokv._pycompat.typing import cast
from denokv.result import Err
from denokv.result import Ok
from denokv.result import Result
Expand Down
6 changes: 3 additions & 3 deletions src/denokv/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

from dataclasses import dataclass
from datetime import datetime
from typing import Mapping
from typing import Sequence
from typing import cast
from uuid import UUID

import aiohttp
Expand All @@ -13,6 +10,9 @@

from denokv._pycompat.dataclasses import slots_if310
from denokv._pycompat.enum import StrEnum
from denokv._pycompat.typing import Mapping
from denokv._pycompat.typing import Sequence
from denokv._pycompat.typing import cast
from denokv._rfc3339 import parse_rfc3339_datetime
from denokv.errors import DenoKvError
from denokv.errors import DenoKvValidationError
Expand Down
10 changes: 4 additions & 6 deletions src/denokv/backoff.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
from dataclasses import dataclass
from enum import IntEnum
from itertools import count
from typing import TYPE_CHECKING
from typing import Callable
from typing import Iterable
from typing import Iterator
from typing import Literal

if TYPE_CHECKING:
from typing_extensions import TypeAlias
from denokv._pycompat.typing import Callable
from denokv._pycompat.typing import Iterable
from denokv._pycompat.typing import Iterator
from denokv._pycompat.typing import TypeAlias

Backoff: TypeAlias = Iterable[float]
"""
Expand Down
Loading
Loading