Enable static type checking with pytype (#298)

* Ignore pytype import errors in google/auth.

These errors are raised because the packages are not required, i.e. not
listed in setup.py. We can't guarantee they'll be installed or that
their pyi files exist in github.com/python/typeshed, so silence
potential errors instead.

This does impact the accuracy of type checking.

* Ignore pytype import errors in transport/.

These imports are not listed in setup.py, because they are optional --
it is assumed the user has them installed if needed. Disabling
import-error for these imports prevents useless errors from pytype.

* Ignore various type errors raised by pytype.

- `__init__.py`: pytype is not aware of `__path__`.
- jwt.py: the pyi file for urllib.unparse is not aware of None. Empty
strings are clearer.

* Add pytype disable comments for scripts/

oauth2client isn't listed as a requirement, so users may not have it
installed.

* Fix lint errors from pytype directives.

* Enable pytype -V3.6.

A few notes:
- Previous commits fixed type errors detected by pytype.
- setup.cfg disables pytype's `pyi-error`. This is necessary due to
incomplete type stubs in https://github.com/python/typeshed.
- This only enables pytype's Python3.6 checks. Python2.7 is supported by
pytype but incomplete type stubs cause spurious type errors.

* Remove pytype directives.

Updates to pytype made these directives unnecessary.

* Move pytype install command.

* Add pytype to tox.

* Remove pytype directives for tox-installed imports.

These imports are handled by setup.py and tox.ini, so they'll be
available when pytype is run under tox.

* Fix lint error.
diff --git a/.gitignore b/.gitignore
index c6ab9e7..88a8b8b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,4 @@
 # Generated files
 pylintrc
 pylintrc.test
+pytype_output/
diff --git a/.travis.yml b/.travis.yml
index 8c67288..43f8e31 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,6 +22,8 @@
     env: TOXENV=py36-system SYSTEM_TEST=1 SKIP_APP_ENGINE_SYSTEM_TEST=1
   - python: 2.7
     env: TOXENV=py27-system SYSTEM_TEST=1 SKIP_APP_ENGINE_SYSTEM_TEST=1
+  - python: 3.6
+    env: TOXENV=pytype
 cache:
   directories:
   - ${HOME}/.cache
diff --git a/google/auth/_oauth2client.py b/google/auth/_oauth2client.py
index 71fd7bf..afe7dc4 100644
--- a/google/auth/_oauth2client.py
+++ b/google/auth/_oauth2client.py
@@ -25,6 +25,7 @@
 
 from google.auth import _helpers
 import google.auth.app_engine
+import google.auth.compute_engine
 import google.oauth2.credentials
 import google.oauth2.service_account
 
@@ -37,7 +38,7 @@
         ImportError('oauth2client is not installed.'), caught_exc)
 
 try:
-    import oauth2client.contrib.appengine
+    import oauth2client.contrib.appengine  # pytype: disable=import-error
     _HAS_APPENGINE = True
 except ImportError:
     _HAS_APPENGINE = False
diff --git a/google/auth/app_engine.py b/google/auth/app_engine.py
index f47dae1..91ba842 100644
--- a/google/auth/app_engine.py
+++ b/google/auth/app_engine.py
@@ -28,10 +28,12 @@
 from google.auth import credentials
 from google.auth import crypt
 
+# pytype: disable=import-error
 try:
     from google.appengine.api import app_identity
 except ImportError:
     app_identity = None
+# pytype: enable=import-error
 
 
 class Signer(crypt.Signer):
diff --git a/google/auth/jwt.py b/google/auth/jwt.py
index ef23db2..3805f37 100644
--- a/google/auth/jwt.py
+++ b/google/auth/jwt.py
@@ -738,7 +738,7 @@
         parts = urllib.parse.urlsplit(url)
         # Strip query string and fragment
         audience = urllib.parse.urlunsplit(
-            (parts.scheme, parts.netloc, parts.path, None, None))
+            (parts.scheme, parts.netloc, parts.path, "", ""))
         token = self._get_jwt_for_audience(audience)
         self.apply(headers, token=token)
 
diff --git a/setup.cfg b/setup.cfg
index 2a9acf1..0f15a38 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,2 +1,17 @@
 [bdist_wheel]
 universal = 1
+
+[pytype]
+# Where to start analysis.
+inputs = .
+# Some files aren't worth analyzing, namely tests. Hidden directories (e.g.
+# .tox) are automatically filtered out.
+exclude = tests system_tests
+# All pytype output goes here.
+output = pytype_output
+# Python version (major.minor) of the target code.
+python_version = 3.6
+# Paths to source code directories, separated by ':'.
+pythonpath = .
+# Errors to disable.
+disable = pyi-error
diff --git a/tox.ini b/tox.ini
index 1c52c4b..59fd6ab 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = lint,py27,py34,py35,py36,pypy,cover
+envlist = lint,py27,py34,py35,py36,pypy,cover,pytype
 
 [testenv]
 deps =
@@ -82,3 +82,11 @@
   flake8
   flake8-import-order
   docutils
+
+[testenv:pytype]
+basepython = python3.6
+commands =
+  pytype
+deps =
+  {[testenv]deps}
+  pytype