Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Link type annotations don't play well with static type checkers (pylance, mypy) #820

Open
ldorigo opened this issue Jan 3, 2024 · 5 comments

Comments

@ldorigo
Copy link

ldorigo commented Jan 3, 2024

Describe the bug

Links to related documents annotated as Link[xx] get the type Link[xx], which gives type errors when trying to access e.g. obj.linkedobj.

To Reproduce

class ConversationMessage(Document):
    id: UUID4 = Field(default_factory=uuid4)
    conversation: Link["Conversation"]

# ... initialize db etc...

 async def get_message(
        message_id: UUID4, conversation_id: UUID4
    ) -> Optional[ConversationMessage]:
        return await ConversationMessage.find_one(
            ConversationMessage.id == message_id,
            ConversationMessage.conversation.id == conversation_id, # Gives Cannot access member "id" for type Link[Conversation]":  Member "id" is unknown
            fetch_links=True,
        )
@roman-right
Copy link
Member

Hi @ldorigo ,

Thank you for the catch!

@ldorigo
Copy link
Author

ldorigo commented Jan 18, 2024

Is there any way or workaround to currently type it properly? I'm having to add #type: ignore all over our codebase 😞

@jafonso-learnwise
Copy link

jafonso-learnwise commented Feb 21, 2024

Yeah in general I would like the typing system to look at a Link[T] and recognize it's actually more like a Union[T, Link[T]].

@kratsg
Copy link

kratsg commented Apr 13, 2024

Just to mention that I've run into this issue as well, so I think the only workaround for now is to ignore the type check on these links or to do casting? That is, either

MyDocument.linked_type # type: ignore[attr-defined]

or

from typing import cast
cast(MyDocument.linked_type, UnderlyingType)

@parnell
Copy link

parnell commented Jun 22, 2024

I'd rather have a more robust solution that was built in with Beanie. But I've had success doing the following as a temporary measure.

from typing import TypeAlias
from beanie import Link as BeanieLink

if TYPE_CHECKING:
    _T = TypeVar("_T", bound=Document)
    Link: TypeAlias = _T
else:
    Link = BeanieLink

What it does is when type checking it aliases Link to be the Document class it's wrapping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants