Repository: HypothesisWorks/hypothesis

Issue:
Vendored modules (hypothesis/vendor/pretty.py) produce type errors with Mypy
As of the 0.62.0 release, when type-checking a Hypothesis-using project with Mypy, at least the `pretty` vendored module raises (valid) type errors:

```
…/hypothesis/vendor/pretty.py:501: error: Module has no attribute "InstanceType"
…/hypothesis/vendor/pretty.py:503: error: Incompatible types in assignment (expression has type "Tuple[Callable[[object], str]]", variable has type "Tuple[Callable[[object], str], Any]")
…/hypothesis/vendor/pretty.py:764: error: Cannot assign to a type
…/hypothesis/vendor/pretty.py:764: error: Cannot assign multiple types to name "_exception_base" without an explicit "Type[...]" annotation
…/hypothesis/vendor/pretty.py:791: error: Module has no attribute "DictProxyType"
…/hypothesis/vendor/pretty.py:792: error: Module has no attribute "DictProxyType"
…/hypothesis/vendor/pretty.py:794: error: Module has no attribute "ClassType"
…/hypothesis/vendor/pretty.py:795: error: Module has no attribute "SliceType"
…/hypothesis/vendor/pretty.py:800: error: Name 'xrange' is not defined
…/hypothesis/vendor/pretty.py:801: error: Name 'long' is not defined
…/hypothesis/vendor/pretty.py:802: error: Name 'unicode' is not defined
…/hypothesis/vendor/pretty.py:808: error: Need type annotation for '_deferred_type_pprinters'
```

(The errors are things like Python 2 compatibility code that isn't valid under Python 3.)

I'm guessing this is due to the `py.typed` marker, which counts everything under the `hypothesis` 
package to be type-checked.

The workaround is to explicitly ignore the module's errors in the project's `mypy.ini`:

```ini
[mypy-hypothesis.vendor.pretty]
ignore_errors = True
```

However, projects should not be expected to do this in general: the fix should be to explicitly annotate the code in question (or the whole module, pending https://github.com/python/mypy/issues/626) with `# type: ignore`.


Discussion:
As an aside, the Hypothesis CI should probably run Mypy too, to avoid this kind of problem.
Ack!  You're entirely right, thanks for reporting this. We actually do run Mypy in CI... but with the vendor directory ignored. Whoops.

I'll fix this as a matter of priority. 

Resolving patch:
diff --git a/hypothesis-python/src/hypothesis/vendor/pretty.py b/hypothesis-python/src/hypothesis/vendor/pretty.py
--- a/hypothesis-python/src/hypothesis/vendor/pretty.py
+++ b/hypothesis-python/src/hypothesis/vendor/pretty.py
@@ -498,9 +498,9 @@ def remove(self, group):
 
 
 try:
-    _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
+    _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)  # type: ignore
 except AttributeError:  # Python 3
-    _baseclass_reprs = (object.__repr__,)
+    _baseclass_reprs = (object.__repr__,)  # type: ignore
 
 
 def _default_pprint(obj, p, cycle):
@@ -761,7 +761,7 @@ def _exception_pprint(obj, p, cycle):
 try:
     _exception_base = BaseException
 except NameError:  # pragma: no cover
-    _exception_base = Exception
+    _exception_base = Exception  # type: ignore
 
 
 #: printers for builtin types
@@ -788,25 +788,24 @@ def _exception_pprint(obj, p, cycle):
 }
 
 try:  # pragma: no cover
-    if types.DictProxyType != dict:
-        _type_pprinters[types.DictProxyType] = _dict_pprinter_factory(
+    if types.DictProxyType != dict:  # type: ignore
+        _type_pprinters[types.DictProxyType] = _dict_pprinter_factory(  # type: ignore
             '<dictproxy {', '}>')
-    _type_pprinters[types.ClassType] = _type_pprint
-    _type_pprinters[types.SliceType] = _repr_pprint
+    _type_pprinters[types.ClassType] = _type_pprint  # type: ignore
+    _type_pprinters[types.SliceType] = _repr_pprint  # type: ignore
 except AttributeError:  # Python 3
     _type_pprinters[slice] = _repr_pprint
 
 try:  # pragma: no cover
-    _type_pprinters[xrange] = _repr_pprint
-    _type_pprinters[long] = _repr_pprint
-    _type_pprinters[unicode] = _repr_pprint
+    _type_pprinters[xrange] = _repr_pprint  # type: ignore
+    _type_pprinters[long] = _repr_pprint  # type: ignore
+    _type_pprinters[unicode] = _repr_pprint  # type: ignore
 except NameError:
     _type_pprinters[range] = _repr_pprint
     _type_pprinters[bytes] = _repr_pprint
 
 #: printers for types specified by name
-_deferred_type_pprinters = {
-}
+_deferred_type_pprinters = {}  # type: ignore
 
 
 def for_type_by_name(type_module, type_name, func):


Test patch: