seandstewart / typical

Typical: Fast, simple, & correct data-validation using Python 3 typing.
https://python-typical.org
MIT License
183 stars 9 forks source link

Transmute is broken with dicts of dataclasses with default values #179

Closed smphhh closed 2 years ago

smphhh commented 2 years ago

Description

Transmute seems to be badly broken in 2.7.1 (2.6.4 works correctly) with dicts of dataclasses with default values.

What I Did

from dataclasses import dataclass
from typing import Dict

import typic

@dataclass()
class FieldOverrideSpec:
    target_name: str
    data_type: str = "default"

FieldOverrideConfig = Dict[str, FieldOverrideSpec]

typic.protocol(FieldOverrideConfig).transmute(
    {"foo": {"target_name": "foo1", "data_type": "int"}}
)

The result I get is {'target_name': FieldOverrideSpec(target_name='data_type', data_type='default')} which is obviously completely wrong. Removing the default value from the dataclass makes transmute work correctly.

seandstewart commented 2 years ago

Hey @smphhh -

It appears this is a side-effect of a dictionary with exactly two fields being compatible with tuple unpacking in Python:

>>> f0, f1 = {'key0': 'val', 'key1': 'val'}

I believe I have a fix in 179/tuple-unpacking-dict-keys - would you mind testing that branch out to verify?

smphhh commented 2 years ago

Hi, yeah that branch does fix it (as well the somewhat more complex case I originally discovered the issue with).