zmievsa / pydantic-duality

Automatically and lazily generate three versions of your pydantic models: one with Extra.forbid, one with Extra.ignore, and one with all fields optional
https://ovsyanka83.github.io/pydantic-duality/
MIT License
31 stars 1 forks source link

Models parsed via __response__ do not pass isinstance() checks against the original model #13

Closed r4victor closed 2 weeks ago

r4victor commented 7 months ago

Describe the bug We're parsing objects using MyModel.__response__, then pass the objects as if they were instances of MyModel. This fails because isinstance(obj, MyModel) return False.

To Reproduce Steps to reproduce the behavior:

  1. Define a model inherited from DualBaseModel
  2. Parse an object using model's __response__.
  3. Call isinstance(). The check fails:
from pydantic_duality import DualBaseModel

class MyModel(DualBaseModel):
    one: str

my_model = MyModel.__response__.parse_obj({"one": "two", "extra": "three"})

print(isinstance(my_model, MyModel))
print(isinstance(my_model, MyModel.__response__))
# False
# True

Expected behavior I'm not sure if this is intended or not and if it should be considered a bug in pydantic-duality, but such behavior was unexpected – it requires to always check for both isinstance(obj, MyModel) and isinstance(obj, MyModel.__response__) when the code works with objects parsed by MyModel.__response__.

Screenshots If applicable, add screenshots to help explain your problem.

Operating system macOS

Additional context Add any other context about the problem here.

zmievsa commented 7 months ago

Hm... I remember explicitly adding the feature to make sure this behavior is impossible. I'll take a look.

zmievsa commented 7 months ago

I looked into it. I did do this for reverse checks ( isinstance(obj, cls.__request__)) but not for the other types of checks. The current architecture is based on building completely different MRO for each object (where cls.__request__ is based on the .__request__ of its parents, and so on) which means that the classes you are trying to compare are completely unrelated.

A completely different architecture seems to be necessary to fix the issue you are referencing. Do you have any ideas?

zmievsa commented 2 weeks ago

Fixed in 1.2.3. Please, check.