Skip to content

Commit a862de4

Browse files
authored
Merge branch 'main' into rm-3.9-workaround
2 parents 22deee3 + 5ecdd63 commit a862de4

File tree

6 files changed

+22
-9
lines changed

6 files changed

+22
-9
lines changed
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from email.headerregistry import Address
2-
from email.message import EmailMessage
1+
from email.headerregistry import Address, BaseHeader
2+
from email.message import EmailMessage, MIMEPart
33
from typing_extensions import assert_type
44

55
msg = EmailMessage()
@@ -8,3 +8,11 @@
88

99
for a in msg.iter_attachments():
1010
assert_type(a, EmailMessage)
11+
12+
generic_msg: EmailMessage[BaseHeader, str] = EmailMessage()
13+
assert_type(generic_msg.get("To"), BaseHeader | None)
14+
assert_type(generic_msg.get_body(), MIMEPart[BaseHeader, str] | None)
15+
for a in generic_msg.iter_attachments():
16+
assert_type(a, EmailMessage[BaseHeader, str])
17+
for p in generic_msg.iter_parts():
18+
assert_type(p, MIMEPart[BaseHeader, str])

stdlib/email/message.pyi

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,15 @@ class Message(Generic[_HeaderT_co, _HeaderParamT_contra]):
151151

152152
class MIMEPart(Message[_HeaderRegistryT_co, _HeaderRegistryParamT_contra]):
153153
def __init__(self, policy: Policy[Any] | None = None) -> None: ...
154-
def get_body(self, preferencelist: Sequence[str] = ("related", "html", "plain")) -> MIMEPart[_HeaderRegistryT_co] | None: ...
154+
def get_body(
155+
self, preferencelist: Sequence[str] = ("related", "html", "plain")
156+
) -> MIMEPart[_HeaderRegistryT_co, _HeaderRegistryParamT_contra] | None: ...
155157
def attach(self, payload: Self) -> None: ... # type: ignore[override]
156158
# The attachments are created via type(self) in the attach method. It's theoretically
157159
# possible to sneak other attachment types into a MIMEPart instance, but could cause
158160
# cause unforseen consequences.
159161
def iter_attachments(self) -> Iterator[Self]: ...
160-
def iter_parts(self) -> Iterator[MIMEPart[_HeaderRegistryT_co]]: ...
162+
def iter_parts(self) -> Iterator[MIMEPart[_HeaderRegistryT_co, _HeaderRegistryParamT_contra]]: ...
161163
def get_content(self, *args: Any, content_manager: ContentManager | None = None, **kw: Any) -> Any: ...
162164
def set_content(self, *args: Any, content_manager: ContentManager | None = None, **kw: Any) -> None: ...
163165
def make_related(self, boundary: str | None = None) -> None: ...
@@ -171,4 +173,4 @@ class MIMEPart(Message[_HeaderRegistryT_co, _HeaderRegistryParamT_contra]):
171173
def as_string(self, unixfrom: bool = False, maxheaderlen: int | None = None, policy: Policy[Any] | None = None) -> str: ...
172174
def is_attachment(self) -> bool: ...
173175

174-
class EmailMessage(MIMEPart): ...
176+
class EmailMessage(MIMEPart[_HeaderRegistryT_co, _HeaderRegistryParamT_contra]): ...

stubs/Authlib/METADATA.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
version = "1.6.10"
1+
version = "1.6.11"
22
upstream-repository = "https://github.com/authlib/authlib"
33
dependencies = ["cryptography"]

stubs/channels/METADATA.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version = "4.3.*"
22
upstream-repository = "https://github.com/django/channels"
3-
dependencies = ["django-stubs>=4.2", "asgiref"]
3+
dependencies = ["django-stubs>=6.0.3", "asgiref"]
44

55
[tool.stubtest]
66
mypy-plugins = ['mypy_django_plugin.main']

stubs/channels/channels/auth.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from _typeshed import Incomplete
2+
13
from asgiref.typing import ASGIReceiveCallable, ASGISendCallable
24
from channels.middleware import BaseMiddleware
35
from django.contrib.auth.backends import BaseBackend
@@ -14,7 +16,7 @@ async def logout(scope: _ChannelScope) -> None: ...
1416

1517
# Inherits AbstractBaseUser to improve autocomplete and show this is a lazy proxy for a user.
1618
# At runtime, it's just a LazyObject that wraps the actual user instance.
17-
class UserLazyObject(AbstractBaseUser, LazyObject): ...
19+
class UserLazyObject(AbstractBaseUser, LazyObject[Incomplete]): ...
1820

1921
class AuthMiddleware(BaseMiddleware):
2022
def populate_scope(self, scope: _ChannelScope) -> None: ...

stubs/channels/channels/consumer.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from _typeshed import Incomplete
12
from collections.abc import Awaitable
23
from typing import Any, ClassVar, Protocol, TypedDict, type_check_only
34

@@ -11,7 +12,7 @@ from django.utils.functional import LazyObject
1112
# We subclass both for type checking purposes to expose SessionBase attributes,
1213
# and suppress mypy's "misc" error with `# type: ignore[misc]`.
1314
@type_check_only
14-
class _LazySession(SessionBase, LazyObject): # type: ignore[misc]
15+
class _LazySession(SessionBase, LazyObject[Incomplete]): # type: ignore[misc]
1516
_wrapped: SessionBase
1617

1718
@type_check_only

0 commit comments

Comments
 (0)