Repository: lovasoa/marshmallow_dataclass

Issue:
Bug: not  allow null in any values
```py
from typing import Any
from typing import Dict

from marshmallow_dataclass import dataclass


@dataclass()
class A:
    data: Dict[str, Any]


A.Schema().load({
    'data': {'inner_data': None}
})
```

Discussion:

Patch:
diff --git a/marshmallow_dataclass/__init__.py b/marshmallow_dataclass/__init__.py
index 403da98..9b223a5 100644
--- a/marshmallow_dataclass/__init__.py
+++ b/marshmallow_dataclass/__init__.py
@@ -319,12 +319,9 @@ def _proxied_class_schema(
 def _field_by_type(
     typ: Union[type, Any], base_schema: Optional[Type[marshmallow.Schema]]
 ) -> Optional[Type[marshmallow.fields.Field]]:
-    if typ is Any:
-        return marshmallow.fields.Raw
-    else:
-        return (
-            base_schema and base_schema.TYPE_MAPPING.get(typ)
-        ) or marshmallow.Schema.TYPE_MAPPING.get(typ)
+    return (
+        base_schema and base_schema.TYPE_MAPPING.get(typ)
+    ) or marshmallow.Schema.TYPE_MAPPING.get(typ)
 
 
 def field_for_schema(
@@ -378,6 +375,10 @@ def field_for_schema(
     if field:
         return field(**metadata)
 
+    if typ is Any:
+        metadata.setdefault("allow_none", True)
+        return marshmallow.fields.Raw(**metadata)
+
     # Generic types
     origin = typing_inspect.get_origin(typ)
     if origin:


Test patch:
diff --git a/tests/test_class_schema.py b/tests/test_class_schema.py
index 5dd6958..094ce37 100644
--- a/tests/test_class_schema.py
+++ b/tests/test_class_schema.py
@@ -1,11 +1,13 @@
-import dataclasses
 import unittest
+from typing import Any
 from uuid import UUID
 
-from marshmallow_dataclass import class_schema
-from marshmallow import Schema
+import dataclasses
+from marshmallow import Schema, ValidationError
 from marshmallow.fields import Field, UUID as UUIDField
 
+from marshmallow_dataclass import class_schema
+
 
 class TestClassSchema(unittest.TestCase):
     def test_simple_unique_schemas(self):
@@ -58,6 +60,24 @@ class TestClassSchema(unittest.TestCase):
         self.assertIsInstance(schema.fields["custom"], CustomField)
         self.assertIsInstance(schema.fields["uuid"], UUIDField)
 
+    def test_any_none(self):
+        # See: https://github.com/lovasoa/marshmallow_dataclass/issues/80
+        @dataclasses.dataclass
+        class A:
+            data: Any
+
+        schema = class_schema(A)()
+        self.assertEqual(A(data=None), schema.load({"data": None}))
+        self.assertEqual(schema.dump(A(data=None)), {"data": None})
+
+    def test_any_none_disallowed(self):
+        @dataclasses.dataclass
+        class A:
+            data: Any = dataclasses.field(metadata={"allow_none": False})
+
+        schema = class_schema(A)()
+        self.assertRaises(ValidationError, lambda: schema.load({"data": None}))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tests/test_field_for_schema.py b/tests/test_field_for_schema.py
index 8f356e9..c597e87 100644
--- a/tests/test_field_for_schema.py
+++ b/tests/test_field_for_schema.py
@@ -29,7 +29,9 @@ class TestFieldForSchema(unittest.TestCase):
         )
 
     def test_any(self):
-        self.assertFieldsEqual(field_for_schema(Any), fields.Raw(required=True))
+        self.assertFieldsEqual(
+            field_for_schema(Any), fields.Raw(required=True, allow_none=True)
+        )
 
     def test_dict_from_typing(self):
         self.assertFieldsEqual(
@@ -45,8 +47,8 @@ class TestFieldForSchema(unittest.TestCase):
         self.assertFieldsEqual(
             field_for_schema(dict),
             fields.Dict(
-                keys=fields.Raw(required=True),
-                values=fields.Raw(required=True),
+                keys=fields.Raw(required=True, allow_none=True),
+                values=fields.Raw(required=True, allow_none=True),
                 required=True,
             ),
         )
@@ -54,7 +56,7 @@ class TestFieldForSchema(unittest.TestCase):
     def test_builtin_list(self):
         self.assertFieldsEqual(
             field_for_schema(list, metadata=dict(required=False)),
-            fields.List(fields.Raw(required=True), required=False),
+            fields.List(fields.Raw(required=True, allow_none=True), required=False),
         )
 
     def test_explicit_field(self):