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] Validation fails in beanie 1.24.0 when dictionary key is an Enum #829

Open
juho-workfellow opened this issue Jan 11, 2024 · 2 comments
Assignees
Labels
bug Something isn't working good first issue Good for newcomers

Comments

@juho-workfellow
Copy link

Describe the bug

#785 introduced a bug here: https://github.com/roman-right/beanie/blob/main/beanie/odm/utils/encoder.py#L134. Now validation fails if dictionary key is an Enum.

To Reproduce

from beanie import Document, init_beanie
from motor.motor_asyncio import AsyncIOMotorClient
from typing import Dict
from enum import Enum
import asyncio


class CategoryEnum(str, Enum):
    CHOCOLATE = "Chocolate"
    CANDY = "Candy"

class Product(Document):
    name: str
    price: float
    category: Dict[CategoryEnum, str]

async def example():
    client = AsyncIOMotorClient(<mongodb_connection>)
    await init_beanie(database=client["test_db"], document_models=[Product])

    chocolate = {CategoryEnum.CHOCOLATE: "description of chocolate"}
    tonybar = Product(name="Tony's", price=1.1, category=chocolate)
    await tonybar.insert()

    product = await Product.find_one()
    print(product)


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

Expected behavior
With beanie 1.23.6 the script prints this on the command line:

id=ObjectId('659fc96a59f26f162d6cf1dc') revision_id=None name="Tony's" price=1.1 category={<CategoryEnum.CHOCOLATE: 'Chocolate'>: 'description of chocolate'}

With beanie 1.24.0:

Traceback (most recent call last):
  File "C:some_path\beanie_bug.py", line 36, in <module>
    asyncio.run(example())
  File "C:\Users\JuhoSalminen\AppData\Local\Programs\Python\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\JuhoSalminen\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
    return future.result()
  File "C:some_path\beanie_bug.py", line 31, in example
    product = await Product.find_one()
  File "C:some_path\.venv\lib\site-packages\beanie\odm\queries\find.py", line 1023, in __await__
    FindQueryResultType, parse_obj(self.projection_model, document)
  File "C:some_path\.venv\lib\site-packages\beanie\odm\utils\parsing.py", line 104, in parse_obj
    result = parse_model(model, data)
  File "C:some_path\.venv\lib\site-packages\beanie\odm\utils\pydantic.py", line 39, in parse_model
    return model_type.parse_obj(data)
  File "pydantic\main.py", line 526, in pydantic.main.BaseModel.parse_obj
  File "C:some_path\.venv\lib\site-packages\beanie\odm\documents.py", line 182, in __init__
    super(Document, self).__init__(*args, **kwargs)
  File "pydantic\main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Product
category -> __key__
  value is not a valid enumeration member; permitted: 'Chocolate', 'Candy' (type=type_error.enum; enum_values=[<CategoryEnum.CHOCOLATE: 'Chocolate'>, <CategoryEnum.CANDY: 'Candy'>])

Replacing line 134 in beanie/odm/utils/encoder.py with return {key: self.encode(value) for key, value in obj.items()} fixes the issue.

@kheyer
Copy link

kheyer commented Jan 30, 2024

Just ran into this. Resolved by downgrading from 1.24.0 to 1.23.6.

@roman-right roman-right added the bug Something isn't working label Feb 8, 2024
@roman-right roman-right self-assigned this Feb 8, 2024
@roman-right
Copy link
Member

Hi! Thank you for the catch! I'll pick it up on the next bug fixing session

@roman-right roman-right added the good first issue Good for newcomers label Feb 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants