Repository: marshmallow-code/marshmallow
Pull request #1618 (2020-06-22 05:53:54)

Bump mypy from 0.780 to 0.781 and pre-commit autoupdate
Bumps [mypy](https://github.com/python/mypy) from 0.780 to 0.781.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/python/mypy/commit/f956142030dee57e7283ad364d9c0c14945cb594"><code>f956142</code></a> Bump version to 0.781</li>
<li><a href="https://github.com/python/mypy/commit/48dbc1c538c8ad3e8e2e5c34f3ec6a0faca55644"><code>48dbc1c</code></a> include mypyc sub directories in the sdist (<a href="https://github-redirect.dependabot.com/python/mypy/issues/8949">#8949</a>)</li>
<li>See full diff in <a href="https://github.com/python/mypy/compare/v0.780...v0.781">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://api.dependabot.com/badges/compatibility_score?dependency-name=mypy&package-manager=pip&previous-version=0.780&new-version=0.781)](https://dependabot.com/compatibility-score/?dependency-name=mypy&package-manager=pip&previous-version=0.780&new-version=0.781)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
Dependabot will **not** automatically merge this PR because this dependency is pre-1.0.0.

[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language
- `@dependabot badge me` will comment on this PR with code to add a "Dependabot enabled" badge to your readme

Additionally, you can set the following in your Dependabot [dashboard](https://app.dependabot.com):
- Update frequency (including time of day and day of week)
- Pull request limits (per update run and/or open at any time)
- Automerge options (never/patch/minor, and dev/runtime dependencies)
- Out-of-range updates (receive only lockfile updates, if desired)
- Security updates (receive only security updates, if desired)



</details>

dependabot-preview[bot]: A newer version of mypy exists, but since this PR has been edited by someone other than Dependabot I haven't updated it. You'll get a PR for the updated version as normal once this PR is merged.

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0197be73..5c749746 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
 - repo: https://github.com/asottile/pyupgrade
-  rev: v1.26.0
+  rev: v2.6.2
   hooks:
   - id: pyupgrade
     args: ["--py3-plus"]
@@ -10,16 +10,16 @@ repos:
   - id: black
     language_version: python3
 - repo: https://gitlab.com/pycqa/flake8
-  rev: 3.7.9
+  rev: 3.8.3
   hooks:
   - id: flake8
-    additional_dependencies: ['flake8-bugbear==20.1.0']
+    additional_dependencies: ['flake8-bugbear==20.1.4']
 - repo: https://github.com/pre-commit/mirrors-mypy
-  rev: v0.780
+  rev: v0.782
   hooks:
   - id: mypy
 - repo: https://github.com/asottile/blacken-docs
-  rev: v1.5.0-1
+  rev: v1.7.0
   hooks:
   - id: blacken-docs
     additional_dependencies: [black==19.10b0]
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 8e0e6538..cb67ab7f 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -149,3 +149,5 @@ Contributors (chronological)
 - Ronan Murphy `@Resinderate <https://github.com/Resinderate>`_
 - Laurie Opperman `@EpicWink <https://github.com/EpicWink>`_
 - Ram Rachum `@cool-RR <https://github.com/cool-RR>`_
+- `@weeix <https://github.com/weeix>`_
+- Juan Norris `@juannorris <https://github.com/juannorris>`_
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f7563b7b..93a6ec08 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -8,6 +8,15 @@ Deprecations:
 
 - `marshmallow.pprint` is deprecated and will be removed in marshmallow 4 (:issue:`1588`).
 
+Support:
+
+- Document ``default_error_messages`` on field classes (:pr:`1619`). Thanks :user:`weeix`.
+
+Bug fixes:
+
+- Fix passing ``only`` and ``exclude`` to ``Nested`` with an ordered ``Schema`` (:pr:`1627`).
+  Thanks :user:`juannorris` for the PR.
+
 3.6.1 (2020-06-02)
 ******************
 
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index f764be0e..367d3628 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -90,7 +90,7 @@ You may not need to output all declared fields every time you use a schema. You
 
     summary_schema = UserSchema(only=("name", "email"))
     summary_schema.dump(user)
-    # {"name": "Monty Python", "email": "monty@python.org"}
+    # {"name": "Monty", "email": "monty@python.org"}
 
 You can also exclude fields by passing in the ``exclude`` parameter.
 
diff --git a/setup.py b/setup.py
index d003d459..44eea3f5 100644
--- a/setup.py
+++ b/setup.py
@@ -4,13 +4,13 @@ from setuptools import setup, find_packages
 EXTRAS_REQUIRE = {
     "tests": ["pytest", "pytz", "simplejson"],
     "lint": [
-        "mypy==0.780",
+        "mypy==0.782",
         "flake8==3.8.3",
         "flake8-bugbear==20.1.4",
         "pre-commit~=2.4",
     ],
     "docs": [
-        "sphinx==3.1.1",
+        "sphinx==3.1.2",
         "sphinx-issues==1.2.0",
         "alabaster==0.7.12",
         "sphinx-version-warning==1.1.2",
@@ -25,7 +25,7 @@ def find_version(fname):
     Raises RuntimeError if not found.
     """
     version = ""
-    with open(fname, "r") as fp:
+    with open(fname) as fp:
         reg = re.compile(r'__version__ = [\'"]([^\'"]*)[\'"]')
         for line in fp:
             m = reg.match(line)
diff --git a/src/marshmallow/fields.py b/src/marshmallow/fields.py
index b4ceab7a..c727292b 100644
--- a/src/marshmallow/fields.py
+++ b/src/marshmallow/fields.py
@@ -452,8 +452,7 @@ class Nested(Field):
         # No
         author = fields.Nested(UserSchema(), only=('id', 'name'))
 
-    :param nested: The Schema class or class name (string)
-        to nest, or ``"self"`` to nest the :class:`Schema` within itself.
+    :param nested: `Schema` instance, class, class name (string), or callable that returns a `Schema` instance.
     :param exclude: A list or tuple of fields to exclude.
     :param only: A list or tuple of fields to marshal. If `None`, all fields are marshalled.
         This parameter takes precedence over ``exclude``.
@@ -463,6 +462,7 @@ class Nested(Field):
     :param kwargs: The same keyword arguments that :class:`Field` receives.
     """
 
+    #: Default error messages.
     default_error_messages = {"type": "Invalid type."}
 
     def __init__(
@@ -522,10 +522,10 @@ class Nested(Field):
                         original = self._schema.only
                     else:  # only=None -> all fields
                         original = self._schema.fields.keys()
-                    self._schema.only = set_class(self.only).intersection(original)
+                    self._schema.only = set_class(self.only) & set_class(original)
                 if self.exclude:
                     original = self._schema.exclude
-                    self._schema.exclude = set_class(self.exclude).union(original)
+                    self._schema.exclude = set_class(self.exclude) | set_class(original)
                 self._schema._init_fields()
             else:
                 if isinstance(nested, type) and issubclass(nested, SchemaABC):
@@ -668,6 +668,7 @@ class List(Field):
         Does not serialize scalar values to single-item lists.
     """
 
+    #: Default error messages.
     default_error_messages = {"invalid": "Not a valid list."}
 
     def __init__(self, cls_or_instance: typing.Union[Field, type], **kwargs):
@@ -736,6 +737,7 @@ class Tuple(Field):
     .. versionadded:: 3.0.0rc4
     """
 
+    #: Default error messages.
     default_error_messages = {"invalid": "Not a valid tuple."}
 
     def __init__(self, tuple_fields, *args, **kwargs):
@@ -805,6 +807,7 @@ class String(Field):
     :param kwargs: The same keyword arguments that :class:`Field` receives.
     """
 
+    #: Default error messages.
     default_error_messages = {
         "invalid": "Not a valid string.",
         "invalid_utf8": "Not a valid utf-8 string.",
@@ -827,6 +830,7 @@ class String(Field):
 class UUID(String):
     """A UUID field."""
 
+    #: Default error messages.
     default_error_messages = {"invalid_uuid": "Not a valid UUID."}
 
     def _validated(self, value) -> typing.Optional[uuid.UUID]:
@@ -856,6 +860,7 @@ class Number(Field):
 
     num_type = float  # type: typing.Type
 
+    #: Default error messages.
     default_error_messages = {
         "invalid": "Not a valid number.",
         "too_large": "Number too large.",
@@ -908,6 +913,8 @@ class Integer(Number):
     """
 
     num_type = int
+
+    #: Default error messages.
     default_error_messages = {"invalid": "Not a valid integer."}
 
     def __init__(self, *, strict: bool = False, **kwargs):
@@ -935,6 +942,8 @@ class Float(Number):
     """
 
     num_type = float
+
+    #: Default error messages.
     default_error_messages = {
         "special": "Special numeric values (nan or infinity) are not permitted."
     }
@@ -990,6 +999,7 @@ class Decimal(Number):
 
     num_type = decimal.Decimal
 
+    #: Default error messages.
     default_error_messages = {
         "special": "Special numeric values (nan or infinity) are not permitted."
     }
@@ -1086,6 +1096,7 @@ class Boolean(Field):
         False,
     }
 
+    #: Default error messages.
     default_error_messages = {"invalid": "Not a valid boolean."}
 
     def __init__(
@@ -1155,6 +1166,7 @@ class DateTime(Field):
 
     SCHEMA_OPTS_VAR_NAME = "datetimeformat"
 
+    #: Default error messages.
     default_error_messages = {
         "invalid": "Not a valid {obj_type}.",
         "invalid_awareness": "Not a valid {awareness} {obj_type}.",
@@ -1282,6 +1294,7 @@ class Time(Field):
     :param kwargs: The same keyword arguments that :class:`Field` receives.
     """
 
+    #: Default error messages.
     default_error_messages = {
         "invalid": "Not a valid time.",
         "format": '"{input}" cannot be formatted as a time.',
@@ -1313,6 +1326,7 @@ class Date(DateTime):
     :param kwargs: The same keyword arguments that :class:`Field` receives.
     """
 
+    #: Default error messages.
     default_error_messages = {
         "invalid": "Not a valid date.",
         "format": '"{input}" cannot be formatted as a date.',
@@ -1356,6 +1370,7 @@ class TimeDelta(Field):
     HOURS = "hours"
     WEEKS = "weeks"
 
+    #: Default error messages.
     default_error_messages = {
         "invalid": "Not a valid period of time.",
         "format": "{input!r} cannot be formatted as a timedelta.",
@@ -1417,6 +1432,8 @@ class Mapping(Field):
     """
 
     mapping_type = dict
+
+    #: Default error messages.
     default_error_messages = {"invalid": "Not a valid mapping type."}
 
     def __init__(
@@ -1561,6 +1578,7 @@ class Url(String):
     :param kwargs: The same keyword arguments that :class:`String` receives.
     """
 
+    #: Default error messages.
     default_error_messages = {"invalid": "Not a valid URL."}
 
     def __init__(
@@ -1593,6 +1611,7 @@ class Email(String):
     :param kwargs: The same keyword arguments that :class:`String` receives.
     """
 
+    #: Default error messages.
     default_error_messages = {"invalid": "Not a valid email address."}
 
     def __init__(self, *args, **kwargs):


Test patch:
diff --git a/tests/test_fields.py b/tests/test_fields.py
index 8671be95..19abeb6b 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -277,6 +277,24 @@ class TestNestedField:
             with pytest.raises(ValidationError):
                 MySchema().load({"nested": {"x": 1}})
 
+    @pytest.mark.parametrize(
+        ("param", "fields_list"), [("only", ["foo"]), ("exclude", ["bar"])]
+    )
+    def test_ordered_instanced_nested_schema_only_and_exclude(self, param, fields_list):
+        class NestedSchema(Schema):
+            foo = fields.String()
+            bar = fields.String()
+
+            class Meta:
+                ordered = True
+
+        class MySchema(Schema):
+            nested = fields.Nested(NestedSchema(), **{param: fields_list})
+
+        assert MySchema().dump({"nested": {"foo": "baz", "bar": "bax"}}) == {
+            "nested": {"foo": "baz"}
+        }
+
 
 class TestListNested:
     @pytest.mark.parametrize("param", ("only", "exclude", "dump_only", "load_only"))
diff --git a/tests/test_schema.py b/tests/test_schema.py
index 398df182..cc06200e 100644
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -47,6 +47,7 @@ from tests.base import (
 
 random.seed(1)
 
+
 # Run tests with both verbose serializer and 'meta' option serializer
 @pytest.mark.parametrize("SchemaClass", [UserSchema, UserMetaSchema])
 def test_serializing_basic_object(SchemaClass, user):