-
-
Notifications
You must be signed in to change notification settings - Fork 32k
dataclasses astuple and asdict crash on recursive dataclass structures / dont support deepcopy memo #94345
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
Comments
as deepcopy itself supports a |
I think adding |
passing it to deepcopy is part of it, but also you want to place every object received, including dataclass instances, in the dict as well, storing the "asdict" form. then you retrieve that object if present rather than recursively calling internal_asdict again (paraphrasing the names here). |
so, this can't work. we create the dict or tuple all at once and we don't use any kind of mutation since we have a dict factory / tuple factory, not to mention you can't create a recursive tuple structure in any case as they are immutable. even if we changed asdict() to use an interim dictionary so that we can mutate them and make a recursive dict structure, there's still no way to pass them through the given as far as passing memo to so at the moment options seem to be:
Keeping in mind that it's looking like option 1 is likely here, for option 3 I could envision something like this:
where the default behavior on recursion detection is to raise an error (which would most easily mean, do nothing differently from what it is right now). If recursive_token is some other object, like any user defined object, then instead of raising, we return that token, so my structure above would look like: {"b": [{"a": TOKEN}]} concretely I don't know how useful this really is. In a more real world sense if I were using asdict() / astuple(), I'd probably want to be able to indicate within a |
In my eyes, it would be really beneficial to see where an object contains itself. The default |
- Use repr(ConfigHelper) in Context.asdict() to avoid RecursionError that occurs when context.transport.spec.add.set["technology"] elements have parent/child relationships. - Handle Enum, Quantity, self in .util.cache. - Log a verbose message on error. - Only use ._util.dataclasses._asdict() on Python <3.13. - Expand tests.
- Use repr(ConfigHelper) in Context.asdict() to avoid RecursionError that occurs when context.transport.spec.add.set["technology"] elements have parent/child relationships. - Handle Enum, Quantity, self in .util.cache. - Log a verbose message on error. - Only use ._util.dataclasses._asdict() on Python <3.13. - Expand tests.
- Use repr(ConfigHelper) in Context.asdict() to avoid RecursionError that occurs when context.transport.spec.add.set["technology"] elements have parent/child relationships. - Handle Enum, Quantity, self in .util.cache. - Log a verbose message on error. - Only use ._util.dataclasses._asdict() on Python <3.13. - Expand tests.
I don't see this mentioned anywhere and it seems a bit unusual, we can't use
asdict()
orastuple()
with dataclasses that have cycles to each other. This is something that is handled by most other stdlib features such as deepcopy, dataclasses stringify, etc.Example below
output:
there seems to be no workaround as these two methods are pretty simple and don't accept any arguments like "check_recursion", IIUC there is also no directive on field() that would change this either?
The text was updated successfully, but these errors were encountered: