Repository: python-attrs/attrs
Pull request #517 (2019-03-12 00:15:10)

Fix validators __all__
# Pull Request Check List

This is just a reminder about the most common mistakes.  Please make sure that you tick all *appropriate* boxes.  But please read our [contribution guide](https://www.attrs.org/en/latest/contributing.html) at least once, it will save you unnecessary review cycles!

If an item doesn't apply to your pull request, **check it anyway** to make it apparent that there's nothing to do.

- [x] Added **tests** for changed code.
- [x] ~~New features have been added to our [Hypothesis testing strategy](https://github.com/python-attrs/attrs/blob/master/tests/strategies.py).~~
- [x] ~~Changes or additions to public APIs are reflected in our type stubs (files ending in ``.pyi``).~~
    - [x] ~~...and used in the stub test file `tests/typing_example.py`.~~
- [x] ~~Updated **documentation** for changed code.~~
    - [x] ~~New functions/classes have to be added to `docs/api.rst` by hand.~~
    - [x] ~~Changes to the signature of `@attr.s()` have to be added by hand too.~~
    - [x] ~~Changed/added classes/methods/functions have appropriate `versionadded`, `versionchanged`, or `deprecated` [directives](http://www.sphinx-doc.org/en/stable/markup/para.html#directive-versionadded).~~
- [x] Documentation in `.rst` files is written using [semantic newlines](https://rhodesmill.org/brandon/2012/one-sentence-per-line/).
- [x] Changes (and possible deprecations) have news fragments in [`changelog.d`](https://github.com/python-attrs/attrs/blob/master/changelog.d).

If you have *any* questions to *any* of the points above, just **submit and ask**!  This checklist is here to *help* you, not to deter you from contributing!


# Description

Apparently in #425 I forgot to add the new validators into `__all__`...PyCharm helpfully reminded me of this as soon as I updated a project to 19.1.0 and went to use them. x_x

hynek: thanks!

Patch:
diff --git a/changelog.d/517.bugfix.rst b/changelog.d/517.bugfix.rst
new file mode 100644
index 0000000..50d3e33
--- /dev/null
+++ b/changelog.d/517.bugfix.rst
@@ -0,0 +1,1 @@
+Updated ``attr.validators.__all__`` to include new validators added in `#425 <https://github.com/python-attrs/attrs/pull/425>`_.
diff --git a/src/attr/validators.py b/src/attr/validators.py
index 7fc4446..9c39dd2 100644
--- a/src/attr/validators.py
+++ b/src/attr/validators.py
@@ -7,7 +7,16 @@ from __future__ import absolute_import, division, print_function
 from ._make import _AndValidator, and_, attrib, attrs
 
 
-__all__ = ["and_", "in_", "instance_of", "optional", "provides"]
+__all__ = [
+    "and_",
+    "deep_iterable",
+    "deep_mapping",
+    "in_",
+    "instance_of",
+    "is_callable",
+    "optional",
+    "provides",
+]
 
 
 @attrs(repr=False, slots=True, hash=True)


Test patch:
diff --git a/tests/test_validators.py b/tests/test_validators.py
index 3fe5e1e..30bf672 100644
--- a/tests/test_validators.py
+++ b/tests/test_validators.py
@@ -31,6 +31,12 @@ class TestInstanceOf(object):
     Tests for `instance_of`.
     """
 
+    def test_in_all(self):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert instance_of.__name__ in validator_module.__all__
+
     def test_success(self):
         """
         Nothing happens if types match.
@@ -86,6 +92,12 @@ def always_fail(_, __, ___):
 
 
 class TestAnd(object):
+    def test_in_all(self):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert and_.__name__ in validator_module.__all__
+
     def test_success(self):
         """
         Succeeds if all wrapped validators succeed.
@@ -132,6 +144,12 @@ class TestProvides(object):
     Tests for `provides`.
     """
 
+    def test_in_all(self):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert provides.__name__ in validator_module.__all__
+
     def test_success(self):
         """
         Nothing happens if value provides requested interface.
@@ -184,6 +202,12 @@ class TestOptional(object):
     Tests for `optional`.
     """
 
+    def test_in_all(self, validator):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert optional.__name__ in validator_module.__all__
+
     def test_success(self, validator):
         """
         Nothing happens if validator succeeds.
@@ -239,6 +263,12 @@ class TestIn_(object):
     Tests for `in_`.
     """
 
+    def test_in_all(self):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert in_.__name__ in validator_module.__all__
+
     def test_success_with_value(self):
         """
         If the value is in our options, nothing happens.
@@ -281,6 +311,12 @@ class TestDeepIterable(object):
     Tests for `deep_iterable`.
     """
 
+    def test_in_all(self):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert deep_iterable.__name__ in validator_module.__all__
+
     def test_success_member_only(self):
         """
         If the member validator succeeds and the iterable validator is not set,
@@ -395,6 +431,12 @@ class TestDeepMapping(object):
     Tests for `deep_mapping`.
     """
 
+    def test_in_all(self):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert deep_mapping.__name__ in validator_module.__all__
+
     def test_success(self):
         """
         If both the key and value validators succeed, nothing happens.
@@ -485,6 +527,12 @@ class TestIsCallable(object):
     Tests for `is_callable`.
     """
 
+    def test_in_all(self):
+        """
+        Verify that this validator is in ``__all__``.
+        """
+        assert is_callable.__name__ in validator_module.__all__
+
     def test_success(self):
         """
         If the value is callable, nothing happens.