Support union type syntax as defined in PEP 604 and implemented in Python 3.10
I have originally reported this to marshmallow as marshmallow-code/marshmallow#1962, because I assumed that the warning comes from there, but it seems that it is emitted by dataclasses_json instead. Therefore, I'm raising an issue in this repository.
A new syntax for union types has been introduced in PEP 604 and implemented in Python 3.10:
dict[str, Union[str, bool]] == dict[str, str | bool]
Unfortunately, it is not currently supported in dataclasses_json:
UserWarning: Unknown type str | bool at XXX: list[dict[str, str | bool]] It's advised to pass the correct marshmallow type to
YYY.
Because of that, we can't ban Union in our linter.
We run the pyupgrade linter which automatically updates the type hints and causes serious issues with this
Actually with light of the new day the problem we see is somewhat more aggressive.
..\..\..\.venv\eligible2\lib\site-packages\marshmallow\schema.py:751: in loads
return self.load(data, many=many, partial=partial, unknown=unknown)
..\..\..\.venv\eligible2\lib\site-packages\marshmallow\schema.py:717: in load
return self._do_load(
..\..\..\.venv\eligible2\lib\site-packages\marshmallow\schema.py:888: in _do_load
result = self._invoke_load_processors(
..\..\..\.venv\eligible2\lib\site-packages\marshmallow\schema.py:1086: in _invoke_load_processors
data = self._invoke_processors(
..\..\..\.venv\eligible2\lib\site-packages\marshmallow\schema.py:1211: in _invoke_processors
data = [processor(item, many=many, **kwargs) for item in data]
..\..\..\.venv\eligible2\lib\site-packages\marshmallow\schema.py:1211: in <listcomp>
data = [processor(item, many=many, **kwargs) for item in data]
..\..\..\.venv\eligible2\lib\site-packages\dataclasses_json\mm.py:335: in make_instance
return _decode_dataclass(cls, kvs, partial)
..\..\..\.venv\eligible2\lib\site-packages\dataclasses_json\core.py:152: in _decode_dataclass
types = get_type_hints(cls)
..\..\..\AppData\Local\Programs\Python\Python38\lib\typing.py:1232: in get_type_hints
value = _eval_type(value, base_globals, localns)
..\..\..\AppData\Local\Programs\Python\Python38\lib\typing.py:270: in _eval_type
return t._evaluate(globalns, localns)
..\..\..\AppData\Local\Programs\Python\Python38\lib\typing.py:518: in _evaluate
eval(self.__forward_code__, globalns, localns),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E TypeError: 'type' object is not subscriptable
<string>:1: TypeError
Actually my issues are related to pyupgrade applying 3.9/3.10 features to 3.8 which can be suppressed with it's --keep-runtime-typing flag.
The issue is still there:
# stdlib imports
from dataclasses import dataclass, field
from typing import Union
# 3rd party imports
from marshmallow import Schema
from marshmallow_dataclass import add_schema
@add_schema
@dataclass
class SchemaClass1:
str_or_int: Union[str, int] = field(default=0)
class_obj1 = SchemaClass1()
class_obj_dump1 = type(class_obj1).Schema().dump(class_obj1)
print(class_obj_dump1)
@add_schema
@dataclass
class SchemaClass2:
str_or_int: str | int = field(default=0)
class_obj2 = SchemaClass2()
class_obj_dump2 = type(class_obj2).Schema().dump(class_obj2)
print(class_obj_dump2)
Results in:
{'str_or_int': 0}
Traceback (most recent call last):
File ".../tests/fake.py", line 28, in <module>
class_obj_dump2 = type(class_obj2).Schema().dump(class_obj2)
File ".../venv/lib/python3.10/site-packages/marshmallow_dataclass/lazy_class_attribute.py", line 33, in __get__
setattr(cls, self.name, self.func())
File ".../venv/lib/python3.10/site-packages/marshmallow_dataclass/__init__.py", line 356, in class_schema
return _internal_class_schema(clazz, base_schema, clazz_frame)
File ".../venv/lib/python3.10/site-packages/marshmallow_dataclass/__init__.py", line 402, in _internal_class_schema
attributes.update(
File ".../venv/lib/python3.10/site-packages/marshmallow_dataclass/__init__.py", line 405, in <genexpr>
field_for_schema(
File ".../venv/lib/python3.10/site-packages/marshmallow_dataclass/__init__.py", line 729, in field_for_schema
or _internal_class_schema(typ, base_schema, typ_frame)
File ".../venv/lib/python3.10/site-packages/marshmallow_dataclass/__init__.py", line 367, in _internal_class_schema
_RECURSION_GUARD.seen_classes[clazz] = clazz.__name__
AttributeError: 'types.UnionType' object has no attribute '__name__'. Did you mean: '__ne__'?
Process finished with exit code 1
@lidatong any update on this? Thank you for looking into it!
@zyv we recently fixed this for T | None, but in your case it seems some other code is failing. I'll retest