Repository: marshmallow-code/marshmallow

Issue:
[version 2.20.0] TypeError: 'NoneType' object is not subscriptable
After update from version 2.19.5 to 2.20.0 I got error for code like:

```python
from marshmallow import Schema, fields, validates


class Bar(Schema):
    value = fields.String()

    @validates('value')  # <- issue here
    def validate_value(self, value):
        pass


class Foo(Schema):
    bar = fields.Nested(Bar)


sch = Foo()

sch.validate({
    'bar': 'invalid',
})
```

```
Traceback (most recent call last):
  File "/_/bug_mschema.py", line 19, in <module>
    'bar': 'invalid',
  File "/_/env/lib/python3.7/site-packages/marshmallow/schema.py", line 628, in validate
    _, errors = self._do_load(data, many, partial=partial, postprocess=False)
  File "/_/env/lib/python3.7/site-packages/marshmallow/schema.py", line 670, in _do_load
    index_errors=self.opts.index_errors,
  File "/_/env/lib/python3.7/site-packages/marshmallow/marshalling.py", line 292, in deserialize
    index=(index if index_errors else None)
  File "/_/env/lib/python3.7/site-packages/marshmallow/marshalling.py", line 65, in call_and_store
    value = getter_func(data)
  File "/_/env/lib/python3.7/site-packages/marshmallow/marshalling.py", line 285, in <lambda>
    data
  File "/_/env/lib/python3.7/site-packages/marshmallow/fields.py", line 265, in deserialize
    output = self._deserialize(value, attr, data)
  File "/_/env/lib/python3.7/site-packages/marshmallow/fields.py", line 465, in _deserialize
    data, errors = self.schema.load(value)
  File "/_/env/lib/python3.7/site-packages/marshmallow/schema.py", line 588, in load
    result, errors = self._do_load(data, many, partial=partial, postprocess=True)
  File "/_/env/lib/python3.7/site-packages/marshmallow/schema.py", line 674, in _do_load
    self._invoke_field_validators(unmarshal, data=result, many=many)
  File "/_/env/lib/python3.7/site-packages/marshmallow/schema.py", line 894, in _invoke_field_validators
    value = data[field_obj.attribute or field_name]
TypeError: 'NoneType' object is not subscriptable
```

Discussion:

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index d8c8d2d8..5f6427c6 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,14 @@
 Changelog
 ---------
 
+2.20.1 (unreleased)
+*******************
+
+Bug fixes:
+
+- Fix bug that raised ``TypeError`` when invalid data type is
+  passed to a nested schema with ``@validates`` (:issue:`1342`).
+
 2.20.0 (2019-08-10)
 *******************
 
diff --git a/src/marshmallow/schema.py b/src/marshmallow/schema.py
index 085c509b..826d2749 100644
--- a/src/marshmallow/schema.py
+++ b/src/marshmallow/schema.py
@@ -877,7 +877,7 @@ class BaseSchema(base.SchemaABC):
                 for idx, item in enumerate(data):
                     try:
                         value = item[field_obj.attribute or field_name]
-                    except KeyError:
+                    except (KeyError, TypeError):
                         pass
                     else:
                         validated_value = unmarshal.call_and_store(
@@ -892,7 +892,7 @@ class BaseSchema(base.SchemaABC):
             else:
                 try:
                     value = data[field_obj.attribute or field_name]
-                except KeyError:
+                except (KeyError, TypeError):
                     pass
                 else:
                     validated_value = unmarshal.call_and_store(


Test patch:
diff --git a/tests/test_marshalling.py b/tests/test_marshalling.py
index 273dada2..8051cc25 100644
--- a/tests/test_marshalling.py
+++ b/tests/test_marshalling.py
@@ -2,7 +2,7 @@
 
 import pytest
 
-from marshmallow import fields, Schema
+from marshmallow import fields, Schema, validates
 from marshmallow.marshalling import Marshaller, Unmarshaller, missing
 from marshmallow.exceptions import ValidationError
 
@@ -283,3 +283,24 @@ class TestUnmarshaller:
 
             assert result is None
             assert excinfo.value.messages == {'foo': {'_schema': ['Invalid input type.']}}
+
+    # Regression test for https://github.com/marshmallow-code/marshmallow/issues/1342
+    def test_deserialize_wrong_nested_type_with_validates_method(self, unmarshal):
+        class TestSchema(Schema):
+            value = fields.String()
+
+            @validates('value')
+            def validate_value(self, value):
+                pass
+
+        data = {
+            'foo': 'not what we need'
+        }
+        fields_dict = {
+            'foo': fields.Nested(TestSchema, required=True)
+        }
+        with pytest.raises(ValidationError) as excinfo:
+            result = unmarshal.deserialize(data, fields_dict)
+
+            assert result is None
+            assert excinfo.value.messages == {'foo': {'_schema': ['Invalid input type.']}}