BeanieODM / beanie

Asynchronous Python ODM for MongoDB
http://beanie-odm.dev/
Apache License 2.0
1.9k stars 201 forks source link

[BUG] optional link type field in the form of union type expression (Link[A] | None bitwise or operation between link type and None) can not be recognized. #951

Open IterableTrucks opened 2 weeks ago

IterableTrucks commented 2 weeks ago

Describe the bug Python 3.10 introduced a new union type expression with | operator, so Optional[Link[A]] is semantically equal to Link[A] | None. However in the latest version of beanie (v1.26.0), the latter form can not be recognized as a link field.

To Reproduce

import asyncio
from typing import Optional
from pydantic import Field
from beanie import Document, Link, init_beanie, BackLink

class Directory(Document):
    files: list[BackLink['File']] | None = Field(json_schema_extra={'original_field': 'directory'})
    name: str

class File(Document):
    name: str
    size: int
    directory: Link[Directory]

async def main():
    await init_beanie(connection_string="mongodb://localhost:27017/test", document_models=[Directory, File])
    assert 'files' in Directory.get_link_fields()

if __name__ == "__main__":
    asyncio.run(main())
import asyncio
from typing import Optional
from pydantic import Field
from beanie import Document, Link, init_beanie, BackLink

class Directory(Document):
    files: Optional[list[BackLink['File']]] = Field(json_schema_extra={'original_field': 'directory'})
    name: str

class File(Document):
    name: str
    size: int
    directory: Link[Directory]

async def main():
    await init_beanie(connection_string="mongodb://localhost:27017/test", document_models=[Directory, File])
    assert 'files' in Directory.get_link_fields()

if __name__ == "__main__":
    asyncio.run(main())

Expected behavior Both forms of optional list backlink can be recognized as link fields.

Additional context beanie version is 1.26.0 Python version is 3.12.3