Update Mypy so I can use PEP 695 type param syntax
This commit is contained in:
parent
3ef3112014
commit
452867699e
10 changed files with 53 additions and 52 deletions
46
pdm.lock
46
pdm.lock
|
@ -2,10 +2,13 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
groups = ["default", "all", "dev"]
|
groups = ["default", "all", "dev", "memcached", "redis", "websockets"]
|
||||||
strategy = ["cross_platform"]
|
strategy = []
|
||||||
lock_version = "4.4.1"
|
lock_version = "4.5.0"
|
||||||
content_hash = "sha256:ddedd388cce9ed181dc2f3786240fc14e19ceb4539f0a360eeb2efb28da63ebe"
|
content_hash = "sha256:fdf0ffc09550df3ba54428f2c6ceb534fc68c4e1633299dbcfd8db9d9f325564"
|
||||||
|
|
||||||
|
[[metadata.targets]]
|
||||||
|
requires_python = ">=3.12"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiocache"
|
name = "aiocache"
|
||||||
|
@ -49,6 +52,9 @@ name = "aiomcache"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Minimal pure python memcached client"
|
summary = "Minimal pure python memcached client"
|
||||||
|
dependencies = [
|
||||||
|
"typing-extensions>=4; python_version < \"3.11\"",
|
||||||
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "aiomcache-0.8.2-py3-none-any.whl", hash = "sha256:9d78d6b6e74e775df18b350b1cddfa96bd2f0a44d49ad27fa87759a3469cef5e"},
|
{file = "aiomcache-0.8.2-py3-none-any.whl", hash = "sha256:9d78d6b6e74e775df18b350b1cddfa96bd2f0a44d49ad27fa87759a3469cef5e"},
|
||||||
{file = "aiomcache-0.8.2.tar.gz", hash = "sha256:43b220d7f499a32a71871c4f457116eb23460fa216e69c1d32b81e3209e51359"},
|
{file = "aiomcache-0.8.2.tar.gz", hash = "sha256:43b220d7f499a32a71871c4f457116eb23460fa216e69c1d32b81e3209e51359"},
|
||||||
|
@ -59,6 +65,9 @@ name = "annotated-types"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Reusable constraint types to use with typing.Annotated"
|
summary = "Reusable constraint types to use with typing.Annotated"
|
||||||
|
dependencies = [
|
||||||
|
"typing-extensions>=4.0.0; python_version < \"3.9\"",
|
||||||
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
|
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
|
||||||
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
||||||
|
@ -69,6 +78,9 @@ name = "attrs"
|
||||||
version = "23.2.0"
|
version = "23.2.0"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "Classes Without Boilerplate"
|
summary = "Classes Without Boilerplate"
|
||||||
|
dependencies = [
|
||||||
|
"importlib-metadata; python_version < \"3.8\"",
|
||||||
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
|
{file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
|
||||||
{file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
|
{file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
|
||||||
|
@ -167,21 +179,22 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "1.10.1"
|
version = "1.11.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Optional static typing for Python"
|
summary = "Optional static typing for Python"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"mypy-extensions>=1.0.0",
|
"mypy-extensions>=1.0.0",
|
||||||
"typing-extensions>=4.1.0",
|
"tomli>=1.1.0; python_version < \"3.11\"",
|
||||||
|
"typing-extensions>=4.6.0",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"},
|
{file = "mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20"},
|
||||||
{file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"},
|
{file = "mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba"},
|
||||||
{file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"},
|
{file = "mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd"},
|
||||||
{file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"},
|
{file = "mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d"},
|
||||||
{file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"},
|
{file = "mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2"},
|
||||||
{file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"},
|
{file = "mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace"},
|
||||||
{file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"},
|
{file = "mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -425,6 +438,11 @@ name = "redis"
|
||||||
version = "5.0.7"
|
version = "5.0.7"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "Python client for Redis database and key-value store"
|
summary = "Python client for Redis database and key-value store"
|
||||||
|
dependencies = [
|
||||||
|
"async-timeout>=4.0.3; python_full_version < \"3.11.3\"",
|
||||||
|
"importlib-metadata>=1.0; python_version < \"3.8\"",
|
||||||
|
"typing-extensions; python_version < \"3.8\"",
|
||||||
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "redis-5.0.7-py3-none-any.whl", hash = "sha256:0e479e24da960c690be5d9b96d21f7b918a98c0cf49af3b6fafaa0753f93a0db"},
|
{file = "redis-5.0.7-py3-none-any.whl", hash = "sha256:0e479e24da960c690be5d9b96d21f7b918a98c0cf49af3b6fafaa0753f93a0db"},
|
||||||
{file = "redis-5.0.7.tar.gz", hash = "sha256:8f611490b93c8109b50adc317b31bfd84fff31def3475b92e7e80bf39f48175b"},
|
{file = "redis-5.0.7.tar.gz", hash = "sha256:8f611490b93c8109b50adc317b31bfd84fff31def3475b92e7e80bf39f48175b"},
|
||||||
|
@ -438,6 +456,7 @@ summary = "Render rich text, tables, progress bars, syntax highlighting, markdow
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"markdown-it-py>=2.2.0",
|
"markdown-it-py>=2.2.0",
|
||||||
"pygments<3.0.0,>=2.13.0",
|
"pygments<3.0.0,>=2.13.0",
|
||||||
|
"typing-extensions<5.0,>=4.0.0; python_version < \"3.9\"",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"},
|
{file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"},
|
||||||
|
@ -534,6 +553,7 @@ summary = "Yet another URL library"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"idna>=2.0",
|
"idna>=2.0",
|
||||||
"multidict>=4.0",
|
"multidict>=4.0",
|
||||||
|
"typing-extensions>=3.7.4; python_version < \"3.8\"",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
|
{file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
|
||||||
|
|
|
@ -56,6 +56,7 @@ build-backend = "pdm.backend"
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
mypy_path = 'stubs'
|
mypy_path = 'stubs'
|
||||||
plugins = ['pydantic.mypy', 'mpd_now_playable.tools.schema.plugin']
|
plugins = ['pydantic.mypy', 'mpd_now_playable.tools.schema.plugin']
|
||||||
|
enable_incomplete_feature = 'NewGenericSyntax'
|
||||||
|
|
||||||
[tool.ruff.lint]
|
[tool.ruff.lint]
|
||||||
select = [
|
select = [
|
||||||
|
@ -104,7 +105,7 @@ excludes = ["**/.mypy_cache"]
|
||||||
|
|
||||||
[tool.pdm.dev-dependencies]
|
[tool.pdm.dev-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
"mypy>=1.7.1",
|
"mypy>=1.11.0",
|
||||||
"ruff>=0.1.6",
|
"ruff>=0.1.6",
|
||||||
"class-doc>=0.2.6",
|
"class-doc>=0.2.6",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Generic, Optional, TypeVar
|
from typing import Any, Optional
|
||||||
|
|
||||||
import ormsgpack
|
import ormsgpack
|
||||||
from aiocache import Cache
|
from aiocache import Cache
|
||||||
|
@ -8,10 +8,8 @@ from aiocache.serializers import BaseSerializer
|
||||||
from pydantic.type_adapter import TypeAdapter
|
from pydantic.type_adapter import TypeAdapter
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
T = TypeVar("T")
|
|
||||||
|
|
||||||
|
class OrmsgpackSerializer[T](BaseSerializer):
|
||||||
class OrmsgpackSerializer(BaseSerializer, Generic[T]):
|
|
||||||
DEFAULT_ENCODING = None
|
DEFAULT_ENCODING = None
|
||||||
|
|
||||||
def __init__(self, schema: TypeAdapter[T]):
|
def __init__(self, schema: TypeAdapter[T]):
|
||||||
|
@ -28,7 +26,7 @@ class OrmsgpackSerializer(BaseSerializer, Generic[T]):
|
||||||
return self.schema.validate_python(data)
|
return self.schema.validate_python(data)
|
||||||
|
|
||||||
|
|
||||||
def make_cache(schema: TypeAdapter[T], url: URL, namespace: str = "") -> Cache[T]:
|
def make_cache[T](schema: TypeAdapter[T], url: URL, namespace: str = "") -> Cache[T]:
|
||||||
backend = Cache.get_scheme_class(url.scheme)
|
backend = Cache.get_scheme_class(url.scheme)
|
||||||
if backend == Cache.MEMORY:
|
if backend == Cache.MEMORY:
|
||||||
return Cache(backend)
|
return Cache(backend)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from os import environ
|
from os import environ
|
||||||
from typing import TypeVar
|
|
||||||
|
|
||||||
from boltons.iterutils import remap
|
from boltons.iterutils import remap
|
||||||
from pytomlpp import load
|
from pytomlpp import load
|
||||||
|
@ -9,8 +8,6 @@ from xdg_base_dirs import xdg_config_home
|
||||||
from .model import Config
|
from .model import Config
|
||||||
|
|
||||||
__all__ = ("loadConfig",)
|
__all__ = ("loadConfig",)
|
||||||
K = TypeVar("K")
|
|
||||||
V = TypeVar("V")
|
|
||||||
|
|
||||||
|
|
||||||
# Sadly this is the kind of function that's incredibly easy to type statically
|
# Sadly this is the kind of function that's incredibly easy to type statically
|
||||||
|
@ -24,7 +21,7 @@ V = TypeVar("V")
|
||||||
# type like NonNullable<T>. Python's type system also doesn't infer a
|
# type like NonNullable<T>. Python's type system also doesn't infer a
|
||||||
# dictionary literal as having a structural type by default in the way
|
# dictionary literal as having a structural type by default in the way
|
||||||
# TypeScript does, of course, so that part wouldn't work anyway.
|
# TypeScript does, of course, so that part wouldn't work anyway.
|
||||||
def withoutNones(data: Mapping[K, V | None]) -> Mapping[K, V]:
|
def withoutNones[K, V](data: Mapping[K, V | None]) -> Mapping[K, V]:
|
||||||
return remap(data, lambda p, k, v: v is not None)
|
return remap(data, lambda p, k, v: v is not None)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
from asyncio import AbstractEventLoop, new_event_loop
|
from asyncio import AbstractEventLoop, new_event_loop
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from typing import Generic, Iterable, Literal, Protocol, TypeVar, cast
|
from typing import Iterable, Literal, Protocol, cast
|
||||||
|
|
||||||
from .config.model import BaseReceiverConfig
|
from .config.model import BaseReceiverConfig
|
||||||
from .playback import Playback
|
from .playback import Playback
|
||||||
from .player import Player
|
from .player import Player
|
||||||
from .tools.types import not_none
|
from .tools.types import not_none
|
||||||
|
|
||||||
T = TypeVar("T", bound=AbstractEventLoop, covariant=True)
|
|
||||||
|
|
||||||
|
class LoopFactory[T: AbstractEventLoop](Protocol):
|
||||||
class LoopFactory(Generic[T], Protocol):
|
|
||||||
@property
|
@property
|
||||||
def is_replaceable(self) -> bool: ...
|
def is_replaceable(self) -> bool: ...
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
from typing import Callable, Protocol, Self, TypeVar
|
from typing import Callable, Protocol, Self
|
||||||
|
|
||||||
from pydantic.type_adapter import TypeAdapter
|
from pydantic.type_adapter import TypeAdapter
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
T = TypeVar("T")
|
|
||||||
|
|
||||||
|
|
||||||
class ModelWithSchema(Protocol):
|
class ModelWithSchema(Protocol):
|
||||||
@property
|
@property
|
||||||
|
@ -13,7 +11,7 @@ class ModelWithSchema(Protocol):
|
||||||
def schema(self) -> TypeAdapter[Self]: ...
|
def schema(self) -> TypeAdapter[Self]: ...
|
||||||
|
|
||||||
|
|
||||||
def schema(schema_id: str) -> Callable[[type[T]], type[T]]:
|
def schema[T](schema_id: str) -> Callable[[type[T]], type[T]]:
|
||||||
def decorate(clazz: type[T]) -> type[T]:
|
def decorate(clazz: type[T]) -> type[T]:
|
||||||
type.__setattr__(clazz, "id", URL(schema_id))
|
type.__setattr__(clazz, "id", URL(schema_id))
|
||||||
type.__setattr__(clazz, "schema", TypeAdapter(clazz))
|
type.__setattr__(clazz, "schema", TypeAdapter(clazz))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from typing import Any, TypeAlias, TypeVar
|
from typing import Any
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"AnyExceptList",
|
"AnyExceptList",
|
||||||
|
@ -28,27 +28,22 @@ AnyExceptList = (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
U = TypeVar("U")
|
def not_none[U](value: U | None) -> U:
|
||||||
V = TypeVar("V")
|
|
||||||
|
|
||||||
|
|
||||||
def not_none(value: U | None) -> U:
|
|
||||||
if value is None:
|
if value is None:
|
||||||
raise ValueError("None should not be possible here.")
|
raise ValueError("None should not be possible here.")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def option_fmap(f: Callable[[U], V], value: U | None) -> V | None:
|
def option_fmap[U, V](f: Callable[[U], V], value: U | None) -> V | None:
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
return f(value)
|
return f(value)
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T", bound=AnyExceptList)
|
type MaybePlural[T: AnyExceptList] = list[T] | T
|
||||||
MaybePlural: TypeAlias = list[T] | T
|
|
||||||
|
|
||||||
|
|
||||||
def un_maybe_plural(value: MaybePlural[T] | None) -> list[T]:
|
def un_maybe_plural[T: AnyExceptList](value: MaybePlural[T] | None) -> list[T]:
|
||||||
match value:
|
match value:
|
||||||
case None:
|
case None:
|
||||||
return []
|
return []
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
from typing import Generic, TypeVar
|
class BaseCache[T]:
|
||||||
|
|
||||||
T = TypeVar("T")
|
|
||||||
|
|
||||||
class BaseCache(Generic[T]):
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_uri_path(path: str) -> dict[str, str]: ...
|
def parse_uri_path(path: str) -> dict[str, str]: ...
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
from typing import ClassVar, Optional, TypeVar
|
from typing import ClassVar, Optional
|
||||||
|
|
||||||
from .base import BaseCache
|
from .base import BaseCache
|
||||||
from .serializers import BaseSerializer
|
from .serializers import BaseSerializer
|
||||||
|
|
||||||
T = TypeVar("T")
|
class Cache[T](BaseCache[T]):
|
||||||
|
|
||||||
class Cache(BaseCache[T]):
|
|
||||||
MEMORY: ClassVar[type[BaseCache]]
|
MEMORY: ClassVar[type[BaseCache]]
|
||||||
REDIS: ClassVar[type[BaseCache] | None]
|
REDIS: ClassVar[type[BaseCache] | None]
|
||||||
MEMCACHED: ClassVar[type[BaseCache] | None]
|
MEMCACHED: ClassVar[type[BaseCache] | None]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from collections.abc import Callable, Mapping
|
from collections.abc import Callable, Mapping
|
||||||
from typing import TypeAlias, TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
# Apparently you need Python 3.13 for type var defaults to work. But since this
|
# Apparently you need Python 3.13 for type var defaults to work. But since this
|
||||||
# is just a stub file, it's okay if they aren't supported at runtime.
|
# is just a stub file, it's okay if they aren't supported at runtime.
|
||||||
|
@ -8,7 +8,7 @@ KOut = TypeVar("KOut", default=KIn)
|
||||||
VIn = TypeVar("VIn")
|
VIn = TypeVar("VIn")
|
||||||
VOut = TypeVar("VOut", default=VIn)
|
VOut = TypeVar("VOut", default=VIn)
|
||||||
|
|
||||||
Path: TypeAlias = tuple[KIn, ...]
|
type Path[KIn] = tuple[KIn, ...]
|
||||||
|
|
||||||
# remap() is Complicated and really difficult to define a type for, so I'm not
|
# remap() is Complicated and really difficult to define a type for, so I'm not
|
||||||
# surprised the boltons package doesn't try to type it for you. This particular
|
# surprised the boltons package doesn't try to type it for you. This particular
|
||||||
|
|
Loading…
Reference in a new issue