Closed andreas-vester closed 3 years ago
Hi @KraxelHuber - I think you are looking for the default value for y
field, something like:
from typing import Optional
@dataclass
class A:
x: str
y: Optional[int] = None
data = {
'x': 'test',
}
result = from_dict(data_class=A, data=data)
assert result == A(x='test')
Am I right?
@konradhalas No, that's not what I meant. However, you couldn't know as I put in an incorrect assertion. Sorry for that!
What I meant is that result
must not have the attribute y
if it has not been assigned explicitely.
In fact, I am looking for this test to pass.
from dataclasses import dataclass
from typing import Optional
import pytest
from dacite import from_dict
@dataclass
class A:
x: str
y: Optional[int] = None
def test_A():
data = {'x': 'test'}
result = from_dict(data_class=A, data=data)
with pytest.raises(AttributeError):
result.y
My reasoning is as follows:
I may have quite a large number of optional arguments in my dataclass. When I apply from_dict
, I want the result to be "clutter-free", i.e. I only want the arguments I explicitely entered to be attributes.
Does that make sense?
@KraxelHuber ok, now I get it :)
Unfortunately it's not possible - not because dacite
doesn't support it, but because data class doesn't work that way. You can not have a field that appears only whey you assign value.
You can try something like (pseudo code):
class IsRequired(Enum):
NOT_REQUIRED = "NOT_REQUIRED"
@dataclass()
class X:
f: Union[int, IsRequired] = IsRequired.NOT_REQUIRED
def __getattribute__(self, name: str) -> Any:
value = super().__getattribute__(name)
if value is IsRequired.NOT_REQUIRED:
raise AttributeError("...")
return value
... but it looks very ugly.
In general, if you have some Optional fields in your
dict
without providing input data for this field,dacite
will automatically attach theNone
value.Here's the example right from the docs (https://pypi.org/project/dacite/):
I need to get rid of such an empty Optional field all together. I am looking for something like this:
assert result == A(x='test')