Skip to content
This repository has been archived by the owner on Dec 14, 2024. It is now read-only.

Defining __init__() with super() on DualBaseModel subclass raises TypeError #6

Open
r4victor opened this issue Mar 4, 2024 · 9 comments · May be fixed by #9
Open

Defining __init__() with super() on DualBaseModel subclass raises TypeError #6

r4victor opened this issue Mar 4, 2024 · 9 comments · May be fixed by #9

Comments

@r4victor
Copy link
Contributor

r4victor commented Mar 4, 2024

I have some pydantic models that define custom __init__() with a call to super(). When migrating to DualBaseModel as my base model, defining such models started to raise TypeError. Here's the minimal example that reproduces the issue:

from pydantic_duality import DualBaseModel

class MyModel(DualBaseModel):
    one: str
    two: str

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

And the traceback:

Traceback (most recent call last):
  File "pyduality.py", line 4, in <module>
    class MyModel(DualBaseModel):
TypeError: __class__ set to <class '__main__.MyModelRequest'> defining 'MyModel' as <class '__main__.MyModel'>

The problem only occurs when having super() inside __init__(). Tested with Python 3.11.2

@zmievsa
Copy link
Owner

zmievsa commented Mar 4, 2024

I'll take a look today. Thanks for reporting this!

@r4victor
Copy link
Contributor Author

r4victor commented Mar 4, 2024

This seems like a relevant discussion: https://stackoverflow.com/questions/72968768/python-metaclasses-handling-double-class-creation-with-same-classcell-attr

Popping the __classcell__ out of the namespace (attrs) solved the problem with TypeError and everything seems to work, but I'm not exactly sure what the consequences of that can be.

Error origin in the CPython source code: https://github.com/python/cpython/blob/17c4849981905fb1c9bfbb2b963b6ee12e3efb2c/Python/bltinmodule.c#L224

Also, a relevant discussion: python/cpython#73456

@r4victor
Copy link
Contributor Author

r4victor commented Mar 4, 2024

@zmievsa, thanks for the package! I'm actually surprised it's not more popular since the need for having both ignore and forbid models seems so basic.

BTW, does pydantic-duality work with pydantic v2?

@zmievsa
Copy link
Owner

zmievsa commented Mar 4, 2024

@r4victor I guess it is not more popular because I never really made a talk/podcast about it :D

But hey: if you would like to help out with duality and become a maintainer -- I would love to help you do so. I am in big need of interested people. And I'm not just talking about development: documentation, examples, popularization -- anything goes, any help would be hugely appreciated.

Pydantic 2 support is still work in progress, sadly. I need to figure out how to fix one of the tests. I have published the pull request where I do this. But if you need it soon, I can take another look at it tomorrow.

@r4victor
Copy link
Contributor Author

r4victor commented Mar 5, 2024

@zmievsa, I'm not interested in maintaining the project per se, but it's likely I'll get involved in some way or the other if we adopt pydantic-duality.

We're currently on pydantic v1, so pydantic v2 support is not a blocker. I was just wondering what the status is.

@zmievsa
Copy link
Owner

zmievsa commented Mar 5, 2024

Got it. Sounds great.

@zmievsa
Copy link
Owner

zmievsa commented Mar 5, 2024

I have taken a look at the discussion on StackOverflow. Seems like a pretty big effort to do everything properly. I'll do my best to finish it within the next week or two but can't guarantee anything -- this situation can get quite tough.

Classmethods and init_subclass stop working correctly once __classcell__ is popped.

@r4victor
Copy link
Contributor Author

r4victor commented Mar 6, 2024

In any case it's not that critical since the issue can be circumvented in most cases by calling base class directly instead of super(). If super() doesn't play nice with the pydantic-duality approach, maybe a note on this behavior will suffice for now.

As I understand CPython errors because it expects different __classcell__. Can it be replaced with the expected one instead of removing it completely?

@zmievsa
Copy link
Owner

zmievsa commented Mar 18, 2024

That's a good question. Not sure which one would be considered "the expected one" here besides the original which we cannot use.

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

Successfully merging a pull request may close this issue.

2 participants