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

ObjectVars wrong _var_type #4269

Closed
benedikt-bartscher opened this issue Oct 30, 2024 · 9 comments
Closed

ObjectVars wrong _var_type #4269

benedikt-bartscher opened this issue Oct 30, 2024 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@benedikt-bartscher
Copy link
Contributor

benedikt-bartscher commented Oct 30, 2024

Describe the bug
ObjectVars are often not automatically detected. Even if they are, the _var_type often ends up being a ObjectVar[dict] instead of the actual type.

For example if you want to access a nested Object you currently often have to do smth like this:

MyState.obj.to(ObjectVar, Obj).other_object.to(ObjectVar, OtherObject).attribute

Without .to(ObjectVar) attribute access ist completly blocked and without specifing the type, it often ends up being a dict which obviously does not have the same annotations as the correct type.

I once create a draft PR (#3911) to at least improve the situation for guess_type. But that is not sufficient, there are many more places where this needs improvement.

To Reproduce
I added some tests to showcase this: #4268

Expected behavior
Reflex is able to handle arbitrary objects with a serializer defined without ToOperations everywhere.

Screenshots

Specifics (please complete the following information):

  • Python Version: 3.13
  • Reflex Version: main
  • OS: arch

Additional context

@benedikt-bartscher benedikt-bartscher added the bug Something isn't working label Oct 30, 2024
Copy link

linear bot commented Oct 30, 2024

@benedikt-bartscher
Copy link
Contributor Author

@adhami3310 there might be a bug in the Var.to method. var_type/base_type is never used

@adhami3310
Copy link
Member

For one, you can do:

MyState.obj.to(Obj).other_object.to(OtherObject).attribute

I will investigate the possible .to bug

@adhami3310
Copy link
Member

You're correct in that base_type isn't being used, it's a relic of modified code that got removed. Although var_type is still being used.

I checked your PR, I don't see any unexpected behavior. The only case I would say is that we don't handle normal classes w/ serializers like base classes. Is it possible to use dataclasses in your case? The issue is that there are logic that pydantic classes and dataclasses provide to retrieve fields and such that would be missing from such a bare class.

@benedikt-bartscher
Copy link
Contributor Author

You're correct in that base_type isn't being used, it's a relic of modified code that got removed. Although var_type is still being used.

Yes, you are right, only base_type is not used, I cleaned it up here: #4271

Is it possible to use dataclasses in your case?

With hacking, everything is possible. But I would rather prefer reflex supporting bare classes as much as possible.

The issue is that there are logic that pydantic classes and dataclasses provide to retrieve fields and such that would be missing from such a bare class.

I thought the only requirement was get_attribute_access_type for which I implemented support for bare classes, bare sqlalchemy etc.
And if we manually apply all the .to(ObjectVar, type_) everything works flawless.

@adhami3310
Copy link
Member

I thought the only requirement was get_attribute_access_type for which I implemented support for bare classes, bare sqlalchemy etc.

We can then try to do that. So we should basically also handle bare classes with serializers. Can you either edit this issue or create a new one with specifically that info?

@benedikt-bartscher
Copy link
Contributor Author

benedikt-bartscher commented Oct 30, 2024

That would be awesome! Just to clarify: While not documented, this all worked flawless before the var refactor, that's why I am raising a bug instead of a feature request.
The only issue is that the new var operations do not work great if you don't use pydantic/dataclasses. And that's basically what this issue is about. However, if you want, I can still open a separate one.

Btw: I just added some failing typing tests in my PR (#4268) as well. I think we can improve this with generics in the to overloads.

@benedikt-bartscher
Copy link
Contributor Author

benedikt-bartscher commented Oct 30, 2024

Next btw:

OBJECT_TYPE = TypeVar("OBJECT_TYPE", bound=Dict)

It seems like ObjectVar is currently typed to "contain" only dict subclasses, the typevar is bound to dict. However, iirc ObjectVar is also used for dataclasses and rx.Base which are no subclasses of dict. Is this intended?

Edit: @adhami3310 wdyt about this cd7214a ?

@adhami3310
Copy link
Member

Is this intended?

half intended, it's sth i long wanted to fix just not bothered enough to do, but yea there should be no bounds for OBJECT_TYPE

wdyt about this

Some overloads only include generic in return, which doesn't make much sense, but i see improvement on some ends, although generally speaking, you're not gaining much from specifying to the static typing what kind of object var it is because we cannot give static typing of wrapped classes anyways

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants