classification
Title: dataclasses should allow frozendict default value
Type: compile error Stage:
Components: Library (Lib) Versions: Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: CCLDArjun, eric.smith, gianni
Priority: normal Keywords:

Created on 2021-07-19 14:06 by gianni, last changed 2021-07-24 06:45 by gianni.

Messages (5)
msg397799 - (view) Author: Gianni Mariani (gianni) Date: 2021-07-19 14:06
Using a frozendict as a default value should not cause an error in dataclasses. The check for mutability is:

   isinstance(f.default, (list, dict, set))

It appears frozendict has been changed to have a dict base class and it now raises an exception.

There should be a way to indicate object mutability as the purpose of the isinstance(f.default, (list, dict, set)) check is for mutable default values.

Using default_factory to work around this issue is cumbersome.
msg397800 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-07-19 14:18
I agree that would be an improvement.
msg398098 - (view) Author: Arjun (CCLDArjun) * Date: 2021-07-23 21:28
Which frozendict does your message concern? I found this in some test: https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Lib/test/test_builtin.py#L741 or are you suggesting any user defined immutable object?

I'm not sure indicating that an object should be immutable to dataclasses will be less cumbersome than default_factory.

Currently, you have to do this:
> x: frozendict = field(default_factory=frozendict)

But, indicating mutability would be something like this:
> x: frozendict = field(mutable=false)
msg398105 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-07-24 00:00
When I originally read this, I read it as frozenset. I agree that there's no good way of telling if an arbitrary class is immutable, so I'm not sure we can do anything here.

So I think we should close this as a rejected idea.
msg398118 - (view) Author: Gianni Mariani (gianni) Date: 2021-07-24 06:45
@Arjun - this is about default values (See the bug description - Using a frozendict as a default value)

Try this:

from frozendict import frozendict
from dataclasses import dataclass

@dataclass
class A:
    a: frozendict = frozendict(a=1)

This used to work until frozendict became a subclass of dict.

Perhaps another fix is to convert any dict to a frozendict? Maybe not.

How would you handle this case? The only thing I figured was:
from frozendict import frozendict, field
from dataclasses import dataclass

AD=frozendict(a=1)
@dataclass
class A:
    a: frozendict = field(default_factory=lambda:AD)

Which imho is cumbersome.
History
Date User Action Args
2021-07-24 06:45:59giannisetmessages: + msg398118
2021-07-24 00:03:17eric.smithsetassignee: eric.smith
2021-07-24 00:00:42eric.smithsetmessages: + msg398105
2021-07-23 21:28:26CCLDArjunsetnosy: + CCLDArjun
messages: + msg398098
2021-07-19 14:18:38eric.smithsetnosy: + eric.smith
messages: + msg397800
2021-07-19 14:06:32giannicreate