Repository: marshmallow-code/marshmallow

Issue:
fields.Date deserialize resulting in datetime
Today I moved from 3.0.0b16 to 3.0.0b17 since I wanted the `format` option for `fields.Date` ([this commit](https://github.com/marshmallow-code/marshmallow/commit/8efb79a8ed45906853c53335b0ca1b36e8528208)). However I'm getting some unexpected results:

    >>> import marshmallow
    >>> print(marshmallow.__version__)
    3.0.0b17
    >>> d = marshmallow.fields.Date(format='%Y-%m-%d')
    >>> result = d.deserialize('2018-01-01')
    >>> print(type(result), result)
    <class 'datetime.datetime'> 2018-01-01 00:00:00

The functionality is greatly desired, however I wasn't expected that using a `format` for a `fields.Date` resulted in a `datetime.datetime`. Is this really intended?

(This is my first issue here. Provide constructive feedback if I should somehow improve my format)

Discussion:

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index bf80e7dc..4f6a064f 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -4,6 +4,11 @@ Changelog
 3.0.0b18 (unreleased)
 +++++++++++++++++++++
 
+Bug fixes:
+
+- Fix ``Date`` deserialization when using custom format (:issue:`1001`). Thanks
+  :user:`Ondkloss` for reporting.
+
 Deprecations/Removals:
 
 - ``prefix`` parameter or ``Schema`` class is removed (:issue:`991`). The same
diff --git a/marshmallow/fields.py b/marshmallow/fields.py
index 893a8b74..d20b2b88 100644
--- a/marshmallow/fields.py
+++ b/marshmallow/fields.py
@@ -981,13 +981,6 @@ class DateTime(Field):
         else:
             return value.strftime(data_format)
 
-    def _create_data_object_from_parsed_value(self, parsed):
-        """Return a datetime from a parsed object that contains the needed info."""
-        return dt.datetime(
-            parsed.year, parsed.month, parsed.day, parsed.hour, parsed.minute,
-            parsed.second,
-        )
-
     def _deserialize(self, value, attr, data):
         if not value:  # Falsy values, e.g. '', None, [] are not valid
             raise self.fail('invalid', obj_type=self.OBJ_TYPE)
@@ -1000,10 +993,14 @@ class DateTime(Field):
                 raise self.fail('invalid', obj_type=self.OBJ_TYPE)
         else:
             try:
-                return dt.datetime.strptime(value, data_format)
+                return self._make_object_from_format(value, data_format)
             except (TypeError, AttributeError, ValueError):
                 raise self.fail('invalid', obj_type=self.OBJ_TYPE)
 
+    @staticmethod
+    def _make_object_from_format(value, data_format):
+        return dt.datetime.strptime(value, data_format)
+
 
 class LocalDateTime(DateTime):
     """A formatted datetime string in localized time, relative to UTC.
@@ -1074,9 +1071,9 @@ class Date(DateTime):
 
     SCHEMA_OPTS_VAR_NAME = 'dateformat'
 
-    def _create_data_object_from_parsed_value(self, parsed):
-        """Return a date from a parsed object that contains the need information."""
-        return dt.date(parsed.year, parsed.month, parsed.day)
+    @staticmethod
+    def _make_object_from_format(value, data_format):
+        return dt.datetime.strptime(value, data_format).date()
 
 
 class TimeDelta(Field):


Test patch:
diff --git a/tests/test_deserialization.py b/tests/test_deserialization.py
index 0f83d5b9..126620ea 100644
--- a/tests/test_deserialization.py
+++ b/tests/test_deserialization.py
@@ -561,12 +561,13 @@ class TestFieldDeserialization:
             field.deserialize(in_value)
         assert excinfo.value.args[0] == 'Not a valid period of time.'
 
-    def test_date_field_deserialization(self):
-        field = fields.Date()
+    @pytest.mark.parametrize('format', (None, '%Y-%m-%d'))
+    def test_date_field_deserialization(self, format):
+        field = fields.Date(format=format)
         d = dt.date(2014, 8, 21)
         iso_date = d.isoformat()
         result = field.deserialize(iso_date)
-        assert isinstance(result, dt.date)
+        assert type(result) == dt.date
         assert_date_equal(result, d)
 
     @pytest.mark.parametrize(