Python Forum

Full Version: ValueError in dataclasses.py - Please help!
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Using Python 3.11.2 on Raspberry PI.

Executing deposit.py...get the following error:

File "/blockchain/staking-deposit-cli/./staking_deposit/deposit.py", line 4, in <module>
from staking_deposit.cli.existing_mnemonic import existing_mnemonic
File "/blockchain/staking-deposit-cli/venv/lib/python3.11/site-packages/staking_deposit/cli/existing_mnemonic.py", line 19, in <module>
from staking_deposit.utils.validation import validate_int_range
File "/blockchain/staking-deposit-cli/venv/lib/python3.11/site-packages/staking_deposit/utils/validation.py", line 24, in <module>
from staking_deposit.credentials import (
File "/blockchain/staking-deposit-cli/venv/lib/python3.11/site-packages/staking_deposit/credentials.py", line 14, in <module>
from staking_deposit.key_handling.keystore import (
File "/blockchain/staking-deposit-cli/venv/lib/python3.11/site-packages/staking_deposit/key_handling/keystore.py", line 62, in <module>
@dataclass
^^^^^^^^^
File "/usr/lib/python3.11/dataclasses.py", line 1220, in dataclass
return wrap(cls)
^^^^^^^^^
File "/usr/lib/python3.11/dataclasses.py", line 1210, in wrap
return _process_class(cls, init, repr, eq, order, unsafe_hash,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/dataclasses.py", line 958, in _process_class
cls_fields.append(_get_field(cls, name, type, kw_only))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/dataclasses.py", line 815, in _get_field
raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'staking_deposit.key_handling.keystore.KeystoreModule'> for field kdf is not allowed: use default_factory

I'm not a python programmer, so I'd really appreciate any help or guidance on how to fix this...?

NB/ A similar problem has been found here:
https://github.com/facebookresearch/fairseq/issues/5012
The Code tries to initialize a mutable object, which is prevented by the logic of dataclasses/fields. The bug is in the module you use, not Python itself. Python prevents this bad mistake.

Reproduction:
from dataclasses import dataclass, field


@dataclass
class Foo:
    names : list[str]= field(default=[])
Error:
Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> @dataclass File "C:\Users\Bianca\AppData\Local\Programs\Python\Python313\Lib\dataclasses.py", line 1305, in dataclass return wrap(cls) File "C:\Users\Bianca\AppData\Local\Programs\Python\Python313\Lib\dataclasses.py", line 1295, in wrap return _process_class(cls, init, repr, eq, order, unsafe_hash, File "C:\Users\Bianca\AppData\Local\Programs\Python\Python313\Lib\dataclasses.py", line 1008, in _process_class cls_fields.append(_get_field(cls, name, type, kw_only)) File "C:\Users\Bianca\AppData\Local\Programs\Python\Python313\Lib\dataclasses.py", line 860, in _get_field raise ValueError(f'mutable default {type(f.default)} for field ' ValueError: mutable default <class 'list'> for field names is not allowed: use default_factory
Correction:
from dataclasses import dataclass, field


@dataclass
class Foo:
    names : list[str]= field(default_factory=list)
Two changes:
  1. Use default_factory instead of default
  2. The default_factory must be a callable, which returns the wanted object. Do not use literals for mutable objects like [] for a list or {} for a dict. Use instead list, dict, set, etc.
The error is a "mutable default" issue in your KeystoreModule dataclass. Change the kdf field definition to use field(default_factory=KeystoreModule) and add from typing import Optional and use Optional[KeystoreModule] as type hint. This creates a new KeystoreModule instance for each dataclass instance, fixing the shared mutable default. If KeystoreModule's __init__ requires arguments, use a lambda or function in default_factory to provide them.
you need to replace the mutable default value with a default_factory. The default_factory is a function that returns a new instance of the mutable object whenever a new instance of the dataclass is created.

from dataclasses import dataclass, field
from typing import Any

@dataclass
class KeystoreModule:
    # Your class definition here
    pass

@dataclass
class SomeClass:
    kdf: KeystoreModule = field(default_factory=KeystoreModule)
In this example, default_factory=KeystoreModule ensures that a new instance of KeystoreModule is created for each instance of SomeClass.

For example, if the original code looks like this:

@dataclass
class SomeClass:
    kdf: KeystoreModule = KeystoreModule()
You should change it to:

@dataclass
class SomeClass:
    kdf: KeystoreModule = field(default_factory=KeystoreModule)
Thanks for your help guys!
Your recommendations worked!