Update six to v1.13.0
diff --git a/tools/third_party/six/CHANGES b/tools/third_party/six/CHANGES
index b399882..ffa7026 100644
--- a/tools/third_party/six/CHANGES
+++ b/tools/third_party/six/CHANGES
@@ -3,6 +3,28 @@
 
 This file lists the changes in each six version.
 
+1.13.0
+------
+
+- Issue #298, pull request #299: Add `six.moves.dbm_ndbm`.
+
+- Issue #155: Add `six.moves.collections_abc`, which aliases the `collections`
+  module on Python 2-3.2 and the `collections.abc` on Python 3.3 and greater.
+
+- Pull request #304: Re-add distutils fallback in `setup.py`.
+
+- Pull request #305: On Python 3.7, `with_metaclass` supports classes using PEP
+  560 features.
+
+1.12.0
+------
+
+- Issue #259, pull request #260: `six.add_metaclass` now preserves
+  `__qualname__` from the original class.
+
+- Pull request #204: Add `six.ensure_binary`, `six.ensure_text`, and
+  `six.ensure_str`.
+
 1.11.0
 ------
 
diff --git a/tools/third_party/six/LICENSE b/tools/third_party/six/LICENSE
index f3068bf..4b05a54 100644
--- a/tools/third_party/six/LICENSE
+++ b/tools/third_party/six/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2010-2017 Benjamin Peterson
+Copyright (c) 2010-2019 Benjamin Peterson
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
diff --git a/tools/third_party/six/PKG-INFO b/tools/third_party/six/PKG-INFO
deleted file mode 100644
index cd5ff4b..0000000
--- a/tools/third_party/six/PKG-INFO
+++ /dev/null
@@ -1,41 +0,0 @@
-Metadata-Version: 1.1
-Name: six
-Version: 1.11.0
-Summary: Python 2 and 3 compatibility utilities
-Home-page: http://pypi.python.org/pypi/six/
-Author: Benjamin Peterson
-Author-email: benjamin@python.org
-License: MIT
-Description: .. image:: http://img.shields.io/pypi/v/six.svg
-           :target: https://pypi.python.org/pypi/six
-        
-        .. image:: https://travis-ci.org/benjaminp/six.svg?branch=master
-            :target: https://travis-ci.org/benjaminp/six
-        
-        .. image:: http://img.shields.io/badge/license-MIT-green.svg
-           :target: https://github.com/benjaminp/six/blob/master/LICENSE
-        
-        Six is a Python 2 and 3 compatibility library.  It provides utility functions
-        for smoothing over the differences between the Python versions with the goal of
-        writing Python code that is compatible on both Python versions.  See the
-        documentation for more information on what is provided.
-        
-        Six supports every Python version since 2.6.  It is contained in only one Python
-        file, so it can be easily copied into your project. (The copyright and license
-        notice must be retained.)
-        
-        Online documentation is at http://six.rtfd.org.
-        
-        Bugs can be reported to https://github.com/benjaminp/six.  The code can also
-        be found there.
-        
-        For questions about six or porting in general, email the python-porting mailing
-        list: https://mail.python.org/mailman/listinfo/python-porting
-        
-Platform: UNKNOWN
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Topic :: Software Development :: Libraries
-Classifier: Topic :: Utilities
diff --git a/tools/third_party/six/README.rst b/tools/third_party/six/README.rst
index c17d8d7..a99e6f5 100644
--- a/tools/third_party/six/README.rst
+++ b/tools/third_party/six/README.rst
@@ -1,11 +1,18 @@
-.. image:: http://img.shields.io/pypi/v/six.svg
-   :target: https://pypi.python.org/pypi/six
+.. image:: https://img.shields.io/pypi/v/six.svg
+   :target: https://pypi.org/project/six/
+   :alt: six on PyPI
 
 .. image:: https://travis-ci.org/benjaminp/six.svg?branch=master
-    :target: https://travis-ci.org/benjaminp/six
+   :target: https://travis-ci.org/benjaminp/six
+   :alt: six on TravisCI
 
-.. image:: http://img.shields.io/badge/license-MIT-green.svg
+.. image:: https://readthedocs.org/projects/six/badge/?version=latest
+   :target: https://six.readthedocs.io/
+   :alt: six's documentation on Read the Docs
+
+.. image:: https://img.shields.io/badge/license-MIT-green.svg
    :target: https://github.com/benjaminp/six/blob/master/LICENSE
+   :alt: MIT License badge
 
 Six is a Python 2 and 3 compatibility library.  It provides utility functions
 for smoothing over the differences between the Python versions with the goal of
@@ -16,7 +23,7 @@
 file, so it can be easily copied into your project. (The copyright and license
 notice must be retained.)
 
-Online documentation is at http://six.rtfd.org.
+Online documentation is at https://six.readthedocs.io/.
 
 Bugs can be reported to https://github.com/benjaminp/six.  The code can also
 be found there.
diff --git a/tools/third_party/six/documentation/conf.py b/tools/third_party/six/documentation/conf.py
index ad925c1..b3d1328 100644
--- a/tools/third_party/six/documentation/conf.py
+++ b/tools/third_party/six/documentation/conf.py
@@ -33,7 +33,7 @@
 
 # General information about the project.
 project = u"six"
-copyright = u"2010-2017, Benjamin Peterson"
+copyright = u"2010-2019, Benjamin Peterson"
 
 sys.path.append(os.path.abspath(os.path.join(".", "..")))
 from six import __version__ as six_version
diff --git a/tools/third_party/six/documentation/index.rst b/tools/third_party/six/documentation/index.rst
index dd0dc6e..b7ec275 100644
--- a/tools/third_party/six/documentation/index.rst
+++ b/tools/third_party/six/documentation/index.rst
@@ -13,7 +13,7 @@
 without modification.  six consists of only one Python file, so it is painless
 to copy into a project.
 
-Six can be downloaded on `PyPi <https://pypi.python.org/pypi/six/>`_.  Its bug
+Six can be downloaded on `PyPI <https://pypi.org/project/six/>`_.  Its bug
 tracker and code hosting is on `GitHub <https://github.com/benjaminp/six>`_.
 
 The name, "six", comes from the fact that 2*3 equals 6.  Why not addition?
@@ -50,8 +50,9 @@
 
 .. data:: class_types
 
-   Possible class types.  In Python 2, this encompasses old-style and new-style
-   classes.  In Python 3, this is just new-styles.
+   Possible class types.  In Python 2, this encompasses old-style
+   :data:`py2:types.ClassType` and new-style ``type`` classes.  In Python 3,
+   this is just ``type``.
 
 
 .. data:: integer_types
@@ -75,7 +76,9 @@
 .. data:: binary_type
 
    Type for representing binary data.  This is :func:`py2:str` in Python 2 and
-   :func:`py3:bytes` in Python 3.
+   :func:`py3:bytes` in Python 3.  Python 2.6 and 2.7 include ``bytes`` as a
+   builtin alias of ``str``, so six’s version is only necessary for Python 2.5
+   compatibility.
 
 
 .. data:: MAXSIZE
@@ -371,7 +374,7 @@
 .. function:: b(data)
 
    A "fake" bytes literal.  *data* should always be a normal string literal.  In
-   Python 2, :func:`b` returns a 8-bit string.  In Python 3, *data* is encoded
+   Python 2, :func:`b` returns an 8-bit string.  In Python 3, *data* is encoded
    with the latin-1 encoding to bytes.
 
 
@@ -433,6 +436,24 @@
    a bytes object iterator in Python 3.
 
 
+.. function:: ensure_binary(s, encoding='utf-8', errors='strict')
+
+   Coerce *s* to :data:`binary_type`. *encoding*, *errors* are the same as
+   :meth:`py3:str.encode`
+
+
+.. function:: ensure_str(s, encoding='utf-8', errors='strict')
+
+   Coerce *s* to ``str``. *encoding*, *errors* are the same as
+   :meth:`py3:str.encode`
+
+
+.. function:: ensure_text(s, encoding='utf-8', errors='strict')
+
+   Coerce *s* to :data:`text_type`. *encoding*, *errors* are the same as
+   :meth:`py3:str.encode`
+
+
 .. data:: StringIO
 
    This is a fake file object for textual data.  It's an alias for
@@ -503,7 +524,7 @@
    from six.moves import html_parser
 
 Similarly, to get the function to reload modules, which was moved from the
-builtin module to the ``imp`` module, use::
+builtin module to the ``importlib`` module, use::
 
    from six.moves import reload_module
 
@@ -563,7 +584,11 @@
 +------------------------------+-------------------------------------+---------------------------------------+
 | ``cStringIO``                | :func:`py2:cStringIO.StringIO`      | :class:`py3:io.StringIO`              |
 +------------------------------+-------------------------------------+---------------------------------------+
-| ``dbm_gnu``                  | :func:`py2:gdbm`                    | :class:`py3:dbm.gnu`                  |
+| ``collections_abc``          | :mod:`py2:collections`              | :mod:`py3:collections.abc` (3.3+)     |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``dbm_gnu``                  | :mod:`py2:gdbm`                     | :mod:`py3:dbm.gnu`                    |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``dbm_ndbm``                 | :mod:`py2:dbm`                      | :mod:`py3:dbm.ndbm`                   |
 +------------------------------+-------------------------------------+---------------------------------------+
 | ``_dummy_thread``            | :mod:`py2:dummy_thread`             | :mod:`py3:_dummy_thread`              |
 +------------------------------+-------------------------------------+---------------------------------------+
diff --git a/tools/third_party/six/setup.cfg b/tools/third_party/six/setup.cfg
index e12068c..317e016 100644
--- a/tools/third_party/six/setup.cfg
+++ b/tools/third_party/six/setup.cfg
@@ -5,17 +5,16 @@
 max-line-length = 100
 ignore = F821
 
+[metadata]
+license_file = LICENSE
+
 [tool:pytest]
-minversion = 2.2.0
-pep8ignore = 
-	documentation/*.py ALL
-	test_six.py ALL
-flakes-ignore = 
-	documentation/*.py ALL
-	test_six.py ALL
-	six.py UndefinedName
+minversion=2.2.0
+pep8ignore =
+    documentation/*.py ALL
+    test_six.py ALL
 
-[egg_info]
-tag_build = 
-tag_date = 0
-
+flakes-ignore =
+    documentation/*.py ALL
+    test_six.py ALL
+    six.py UndefinedName
diff --git a/tools/third_party/six/setup.py b/tools/third_party/six/setup.py
index ca44e10..97c685b 100644
--- a/tools/third_party/six/setup.py
+++ b/tools/third_party/six/setup.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2010-2017 Benjamin Peterson
+# Copyright (c) 2010-2019 Benjamin Peterson
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -31,6 +31,7 @@
 import six
 
 six_classifiers = [
+    "Development Status :: 5 - Production/Stable",
     "Programming Language :: Python :: 2",
     "Programming Language :: Python :: 3",
     "Intended Audience :: Developers",
@@ -46,11 +47,12 @@
       version=six.__version__,
       author="Benjamin Peterson",
       author_email="benjamin@python.org",
-      url="http://pypi.python.org/pypi/six/",
+      url="https://github.com/benjaminp/six",
       tests_require=["pytest"],
       py_modules=["six"],
       description="Python 2 and 3 compatibility utilities",
       long_description=six_long_description,
       license="MIT",
-      classifiers=six_classifiers
+      classifiers=six_classifiers,
+      python_requires=">=2.6, !=3.0.*, !=3.1.*",
       )
diff --git a/tools/third_party/six/six-1.13.0.dist-info/INSTALLER b/tools/third_party/six/six-1.13.0.dist-info/INSTALLER
new file mode 100644
index 0000000..a1b589e
--- /dev/null
+++ b/tools/third_party/six/six-1.13.0.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/tools/third_party/six/six-1.13.0.dist-info/LICENSE b/tools/third_party/six/six-1.13.0.dist-info/LICENSE
new file mode 100644
index 0000000..4b05a54
--- /dev/null
+++ b/tools/third_party/six/six-1.13.0.dist-info/LICENSE
@@ -0,0 +1,18 @@
+Copyright (c) 2010-2019 Benjamin Peterson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/tools/third_party/six/six-1.13.0.dist-info/METADATA b/tools/third_party/six/six-1.13.0.dist-info/METADATA
new file mode 100644
index 0000000..b0c8f51
--- /dev/null
+++ b/tools/third_party/six/six-1.13.0.dist-info/METADATA
@@ -0,0 +1,52 @@
+Metadata-Version: 2.1
+Name: six
+Version: 1.13.0
+Summary: Python 2 and 3 compatibility utilities
+Home-page: https://github.com/benjaminp/six
+Author: Benjamin Peterson
+Author-email: benjamin@python.org
+License: MIT
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 3
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Topic :: Software Development :: Libraries
+Classifier: Topic :: Utilities
+Requires-Python: >=2.6, !=3.0.*, !=3.1.*
+
+.. image:: https://img.shields.io/pypi/v/six.svg
+   :target: https://pypi.org/project/six/
+   :alt: six on PyPI
+
+.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master
+   :target: https://travis-ci.org/benjaminp/six
+   :alt: six on TravisCI
+
+.. image:: https://readthedocs.org/projects/six/badge/?version=latest
+   :target: https://six.readthedocs.io/
+   :alt: six's documentation on Read the Docs
+
+.. image:: https://img.shields.io/badge/license-MIT-green.svg
+   :target: https://github.com/benjaminp/six/blob/master/LICENSE
+   :alt: MIT License badge
+
+Six is a Python 2 and 3 compatibility library.  It provides utility functions
+for smoothing over the differences between the Python versions with the goal of
+writing Python code that is compatible on both Python versions.  See the
+documentation for more information on what is provided.
+
+Six supports every Python version since 2.6.  It is contained in only one Python
+file, so it can be easily copied into your project. (The copyright and license
+notice must be retained.)
+
+Online documentation is at https://six.readthedocs.io/.
+
+Bugs can be reported to https://github.com/benjaminp/six.  The code can also
+be found there.
+
+For questions about six or porting in general, email the python-porting mailing
+list: https://mail.python.org/mailman/listinfo/python-porting
+
+
diff --git a/tools/third_party/six/six-1.13.0.dist-info/RECORD b/tools/third_party/six/six-1.13.0.dist-info/RECORD
new file mode 100644
index 0000000..e57665c
--- /dev/null
+++ b/tools/third_party/six/six-1.13.0.dist-info/RECORD
@@ -0,0 +1,8 @@
+six-1.13.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4

+six-1.13.0.dist-info/LICENSE,sha256=t1KbjAcXGniow2wyg5BVKOSBKUXZd9El65JujMvyRbY,1066

+six-1.13.0.dist-info/METADATA,sha256=hxS4rSPRfO8ewbcLS30anoFi6LFgUQ3mk_xknZ8RV4w,1940

+six-1.13.0.dist-info/RECORD,,

+six-1.13.0.dist-info/WHEEL,sha256=8T8fxefr_r-A79qbOJ9d_AaEgkpCGmEPHc-gpCq5BRg,110

+six-1.13.0.dist-info/top_level.txt,sha256=_iVH_iYEtEXnD8nYGQYpYFUvkUW9sEO1GYbkeKSAais,4

+six.py,sha256=o9WHO8utWGayNhNqDmNqPdQsQair5RaRWjL_8IYf1qw,33051

+six.pyc,,

diff --git a/tools/third_party/six/six-1.13.0.dist-info/WHEEL b/tools/third_party/six/six-1.13.0.dist-info/WHEEL
new file mode 100644
index 0000000..1001235
--- /dev/null
+++ b/tools/third_party/six/six-1.13.0.dist-info/WHEEL
@@ -0,0 +1,6 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.32.1)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+
diff --git a/tools/third_party/six/six.egg-info/top_level.txt b/tools/third_party/six/six-1.13.0.dist-info/top_level.txt
similarity index 100%
rename from tools/third_party/six/six.egg-info/top_level.txt
rename to tools/third_party/six/six-1.13.0.dist-info/top_level.txt
diff --git a/tools/third_party/six/six.egg-info/PKG-INFO b/tools/third_party/six/six.egg-info/PKG-INFO
deleted file mode 100644
index cd5ff4b..0000000
--- a/tools/third_party/six/six.egg-info/PKG-INFO
+++ /dev/null
@@ -1,41 +0,0 @@
-Metadata-Version: 1.1
-Name: six
-Version: 1.11.0
-Summary: Python 2 and 3 compatibility utilities
-Home-page: http://pypi.python.org/pypi/six/
-Author: Benjamin Peterson
-Author-email: benjamin@python.org
-License: MIT
-Description: .. image:: http://img.shields.io/pypi/v/six.svg
-           :target: https://pypi.python.org/pypi/six
-        
-        .. image:: https://travis-ci.org/benjaminp/six.svg?branch=master
-            :target: https://travis-ci.org/benjaminp/six
-        
-        .. image:: http://img.shields.io/badge/license-MIT-green.svg
-           :target: https://github.com/benjaminp/six/blob/master/LICENSE
-        
-        Six is a Python 2 and 3 compatibility library.  It provides utility functions
-        for smoothing over the differences between the Python versions with the goal of
-        writing Python code that is compatible on both Python versions.  See the
-        documentation for more information on what is provided.
-        
-        Six supports every Python version since 2.6.  It is contained in only one Python
-        file, so it can be easily copied into your project. (The copyright and license
-        notice must be retained.)
-        
-        Online documentation is at http://six.rtfd.org.
-        
-        Bugs can be reported to https://github.com/benjaminp/six.  The code can also
-        be found there.
-        
-        For questions about six or porting in general, email the python-porting mailing
-        list: https://mail.python.org/mailman/listinfo/python-porting
-        
-Platform: UNKNOWN
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Topic :: Software Development :: Libraries
-Classifier: Topic :: Utilities
diff --git a/tools/third_party/six/six.egg-info/SOURCES.txt b/tools/third_party/six/six.egg-info/SOURCES.txt
deleted file mode 100644
index 9a7f3de..0000000
--- a/tools/third_party/six/six.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-CHANGES
-LICENSE
-MANIFEST.in
-README.rst
-setup.cfg
-setup.py
-six.py
-test_six.py
-documentation/Makefile
-documentation/conf.py
-documentation/index.rst
-six.egg-info/PKG-INFO
-six.egg-info/SOURCES.txt
-six.egg-info/dependency_links.txt
-six.egg-info/top_level.txt
\ No newline at end of file
diff --git a/tools/third_party/six/six.egg-info/dependency_links.txt b/tools/third_party/six/six.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/tools/third_party/six/six.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tools/third_party/six/six.py b/tools/third_party/six/six.py
index 6bf4fd3..d0aece8 100644
--- a/tools/third_party/six/six.py
+++ b/tools/third_party/six/six.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2010-2017 Benjamin Peterson
+# Copyright (c) 2010-2019 Benjamin Peterson
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -29,7 +29,7 @@
 import types
 
 __author__ = "Benjamin Peterson <benjamin@python.org>"
-__version__ = "1.11.0"
+__version__ = "1.13.0"
 
 
 # Useful for very coarse version differentiation.
@@ -255,8 +255,10 @@
     MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
     MovedModule("builtins", "__builtin__"),
     MovedModule("configparser", "ConfigParser"),
+    MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
     MovedModule("copyreg", "copy_reg"),
     MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+    MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
     MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
     MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
     MovedModule("http_cookies", "Cookie", "http.cookies"),
@@ -637,6 +639,7 @@
     import io
     StringIO = io.StringIO
     BytesIO = io.BytesIO
+    del io
     _assertCountEqual = "assertCountEqual"
     if sys.version_info[1] <= 1:
         _assertRaisesRegex = "assertRaisesRegexp"
@@ -824,7 +827,15 @@
     class metaclass(type):
 
         def __new__(cls, name, this_bases, d):
-            return meta(name, bases, d)
+            if sys.version_info[:2] >= (3, 7):
+                # This version introduced PEP 560 that requires a bit
+                # of extra care (we mimic what is done by __build_class__).
+                resolved_bases = types.resolve_bases(bases)
+                if resolved_bases is not bases:
+                    d['__orig_bases__'] = bases
+            else:
+                resolved_bases = bases
+            return meta(name, resolved_bases, d)
 
         @classmethod
         def __prepare__(cls, name, this_bases):
@@ -844,13 +855,74 @@
                 orig_vars.pop(slots_var)
         orig_vars.pop('__dict__', None)
         orig_vars.pop('__weakref__', None)
+        if hasattr(cls, '__qualname__'):
+            orig_vars['__qualname__'] = cls.__qualname__
         return metaclass(cls.__name__, cls.__bases__, orig_vars)
     return wrapper
 
 
+def ensure_binary(s, encoding='utf-8', errors='strict'):
+    """Coerce **s** to six.binary_type.
+
+    For Python 2:
+      - `unicode` -> encoded to `str`
+      - `str` -> `str`
+
+    For Python 3:
+      - `str` -> encoded to `bytes`
+      - `bytes` -> `bytes`
+    """
+    if isinstance(s, text_type):
+        return s.encode(encoding, errors)
+    elif isinstance(s, binary_type):
+        return s
+    else:
+        raise TypeError("not expecting type '%s'" % type(s))
+
+
+def ensure_str(s, encoding='utf-8', errors='strict'):
+    """Coerce *s* to `str`.
+
+    For Python 2:
+      - `unicode` -> encoded to `str`
+      - `str` -> `str`
+
+    For Python 3:
+      - `str` -> `str`
+      - `bytes` -> decoded to `str`
+    """
+    if not isinstance(s, (text_type, binary_type)):
+        raise TypeError("not expecting type '%s'" % type(s))
+    if PY2 and isinstance(s, text_type):
+        s = s.encode(encoding, errors)
+    elif PY3 and isinstance(s, binary_type):
+        s = s.decode(encoding, errors)
+    return s
+
+
+def ensure_text(s, encoding='utf-8', errors='strict'):
+    """Coerce *s* to six.text_type.
+
+    For Python 2:
+      - `unicode` -> `unicode`
+      - `str` -> `unicode`
+
+    For Python 3:
+      - `str` -> `str`
+      - `bytes` -> decoded to `str`
+    """
+    if isinstance(s, binary_type):
+        return s.decode(encoding, errors)
+    elif isinstance(s, text_type):
+        return s
+    else:
+        raise TypeError("not expecting type '%s'" % type(s))
+
+
+
 def python_2_unicode_compatible(klass):
     """
-    A decorator that defines __unicode__ and __str__ methods under Python 2.
+    A class decorator that defines __unicode__ and __str__ methods under Python 2.
     Under Python 3 it does nothing.
 
     To support Python 2 and 3 with a single code base, define a __str__ method
diff --git a/tools/third_party/six/test_six.py b/tools/third_party/six/test_six.py
index 43e7426..3eefce3 100644
--- a/tools/third_party/six/test_six.py
+++ b/tools/third_party/six/test_six.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2010-2017 Benjamin Peterson
+# Copyright (c) 2010-2019 Benjamin Peterson
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -22,8 +22,9 @@
 import sys
 import types
 import unittest
+import abc
 
-import py
+import pytest
 
 import six
 
@@ -80,7 +81,7 @@
     except AttributeError:
         # Before Python 2.6.
         pass
-    py.test.raises(
+    pytest.raises(
         (ValueError, OverflowError),
         operator.mul, [None], six.MAXSIZE + 1)
 
@@ -112,7 +113,7 @@
     except ImportError:
         have_gdbm = False
 
-@py.test.mark.parametrize("item_name",
+@pytest.mark.parametrize("item_name",
                           [item.name for item in six._moved_attributes])
 def test_move_items(item_name):
     """Ensure that everything loads correctly."""
@@ -122,36 +123,36 @@
             __import__("six.moves." + item_name)
     except AttributeError:
         if item_name == "zip_longest" and sys.version_info < (2, 6):
-            py.test.skip("zip_longest only available on 2.6+")
+            pytest.skip("zip_longest only available on 2.6+")
     except ImportError:
         if item_name == "winreg" and not sys.platform.startswith("win"):
-            py.test.skip("Windows only module")
+            pytest.skip("Windows only module")
         if item_name.startswith("tkinter"):
             if not have_tkinter:
-                py.test.skip("requires tkinter")
+                pytest.skip("requires tkinter")
             if item_name == "tkinter_ttk" and sys.version_info[:2] <= (2, 6):
-                py.test.skip("ttk only available on 2.7+")
+                pytest.skip("ttk only available on 2.7+")
         if item_name.startswith("dbm_gnu") and not have_gdbm:
-            py.test.skip("requires gdbm")
+            pytest.skip("requires gdbm")
         raise
     if sys.version_info[:2] >= (2, 6):
         assert item_name in dir(six.moves)
 
 
-@py.test.mark.parametrize("item_name",
+@pytest.mark.parametrize("item_name",
                           [item.name for item in six._urllib_parse_moved_attributes])
 def test_move_items_urllib_parse(item_name):
     """Ensure that everything loads correctly."""
     if item_name == "ParseResult" and sys.version_info < (2, 5):
-        py.test.skip("ParseResult is only found on 2.5+")
+        pytest.skip("ParseResult is only found on 2.5+")
     if item_name in ("parse_qs", "parse_qsl") and sys.version_info < (2, 6):
-        py.test.skip("parse_qs[l] is new in 2.6")
+        pytest.skip("parse_qs[l] is new in 2.6")
     if sys.version_info[:2] >= (2, 6):
         assert item_name in dir(six.moves.urllib.parse)
     getattr(six.moves.urllib.parse, item_name)
 
 
-@py.test.mark.parametrize("item_name",
+@pytest.mark.parametrize("item_name",
                           [item.name for item in six._urllib_error_moved_attributes])
 def test_move_items_urllib_error(item_name):
     """Ensure that everything loads correctly."""
@@ -160,7 +161,7 @@
     getattr(six.moves.urllib.error, item_name)
 
 
-@py.test.mark.parametrize("item_name",
+@pytest.mark.parametrize("item_name",
                           [item.name for item in six._urllib_request_moved_attributes])
 def test_move_items_urllib_request(item_name):
     """Ensure that everything loads correctly."""
@@ -169,7 +170,7 @@
     getattr(six.moves.urllib.request, item_name)
 
 
-@py.test.mark.parametrize("item_name",
+@pytest.mark.parametrize("item_name",
                           [item.name for item in six._urllib_response_moved_attributes])
 def test_move_items_urllib_response(item_name):
     """Ensure that everything loads correctly."""
@@ -178,7 +179,7 @@
     getattr(six.moves.urllib.response, item_name)
 
 
-@py.test.mark.parametrize("item_name",
+@pytest.mark.parametrize("item_name",
                           [item.name for item in six._urllib_robotparser_moved_attributes])
 def test_move_items_urllib_robotparser(item_name):
     """Ensure that everything loads correctly."""
@@ -243,7 +244,7 @@
     assert six.advance_iterator(zip(range(2), range(2))) == (0, 0)
 
 
-@py.test.mark.skipif("sys.version_info < (2, 6)")
+@pytest.mark.skipif("sys.version_info < (2, 6)")
 def test_zip_longest():
     from six.moves import zip_longest
     it = zip_longest(range(2), range(1))
@@ -321,7 +322,7 @@
 
 
     def test_empty_remove(self):
-        py.test.raises(AttributeError, six.remove_move, "eggs")
+        pytest.raises(AttributeError, six.remove_move, "eggs")
 
 
 def test_get_unbound_function():
@@ -337,7 +338,7 @@
             pass
     x = X()
     assert six.get_method_self(x.m) is x
-    py.test.raises(AttributeError, six.get_method_self, 42)
+    pytest.raises(AttributeError, six.get_method_self, 42)
 
 
 def test_get_method_function():
@@ -346,7 +347,7 @@
             pass
     x = X()
     assert six.get_method_function(x.m) is X.__dict__["m"]
-    py.test.raises(AttributeError, six.get_method_function, hasattr)
+    pytest.raises(AttributeError, six.get_method_function, hasattr)
 
 
 def test_get_function_closure():
@@ -364,7 +365,7 @@
         pass
     assert isinstance(six.get_function_code(f), types.CodeType)
     if not hasattr(sys, "pypy_version_info"):
-        py.test.raises(AttributeError, six.get_function_code, hasattr)
+        pytest.raises(AttributeError, six.get_function_code, hasattr)
 
 
 def test_get_function_defaults():
@@ -404,7 +405,7 @@
         it = meth(d)
         assert not isinstance(it, list)
         assert list(it) == list(getattr(d, name)())
-        py.test.raises(StopIteration, six.advance_iterator, it)
+        pytest.raises(StopIteration, six.advance_iterator, it)
         record = []
         def with_kw(*args, **kw):
             record.append(kw["kw"])
@@ -416,17 +417,9 @@
         monkeypatch.undo()
 
 
-@py.test.mark.skipif("sys.version_info[:2] < (2, 7)",
+@pytest.mark.skipif("sys.version_info[:2] < (2, 7)",
                 reason="view methods on dictionaries only available on 2.7+")
 def test_dictionary_views():
-    def stock_method_name(viewwhat):
-        """Given a method suffix like "keys" or "values", return the name
-        of the dict method that delivers those on the version of Python
-        we're running in."""
-        if six.PY3:
-            return viewwhat
-        return 'view' + viewwhat
-
     d = dict(zip(range(10), (range(11, 20))))
     for name in "keys", "values", "items":
         meth = getattr(six, "view" + name)
@@ -440,8 +433,8 @@
     it = iter(l)
     assert six.next(it) == 1
     assert six.next(it) == 2
-    py.test.raises(StopIteration, six.next, it)
-    py.test.raises(StopIteration, six.next, it)
+    pytest.raises(StopIteration, six.next, it)
+    pytest.raises(StopIteration, six.next, it)
 
 
 def test_iterator():
@@ -489,7 +482,7 @@
     def f(self):
         return self
     u = six.create_unbound_method(f, X)
-    py.test.raises(TypeError, u)
+    pytest.raises(TypeError, u)
     if six.PY2:
         assert isinstance(u, types.MethodType)
     x = X()
@@ -537,13 +530,13 @@
 
 def test_int2byte():
     assert six.int2byte(3) == six.b("\x03")
-    py.test.raises(Exception, six.int2byte, 256)
+    pytest.raises(Exception, six.int2byte, 256)
 
 
 def test_byte2int():
     assert six.byte2int(six.b("\x03")) == 3
     assert six.byte2int(six.b("\x03\x04")) == 3
-    py.test.raises(IndexError, six.byte2int, six.b(""))
+    pytest.raises(IndexError, six.byte2int, six.b(""))
 
 
 def test_bytesindex():
@@ -554,7 +547,7 @@
     it = six.iterbytes(six.b("hi"))
     assert six.next(it) == ord("h")
     assert six.next(it) == ord("i")
-    py.test.raises(StopIteration, six.next, it)
+    pytest.raises(StopIteration, six.next, it)
 
 
 def test_StringIO():
@@ -689,7 +682,7 @@
     assert out.flushed
 
 
-@py.test.mark.skipif("sys.version_info[:2] >= (2, 6)")
+@pytest.mark.skipif("sys.version_info[:2] >= (2, 6)")
 def test_print_encoding(monkeypatch):
     # Fool the type checking in print_.
     monkeypatch.setattr(six, "file", six.BytesIO, raising=False)
@@ -701,16 +694,16 @@
     out = six.BytesIO()
     out.encoding = "ascii"
     out.errors = "strict"
-    py.test.raises(UnicodeEncodeError, six.print_, six.u("\u053c"), file=out)
+    pytest.raises(UnicodeEncodeError, six.print_, six.u("\u053c"), file=out)
     out.errors = "backslashreplace"
     six.print_(six.u("\u053c"), end="", file=out)
     assert out.getvalue() == six.b("\\u053c")
 
 
 def test_print_exceptions():
-    py.test.raises(TypeError, six.print_, x=3)
-    py.test.raises(TypeError, six.print_, end=3)
-    py.test.raises(TypeError, six.print_, sep=42)
+    pytest.raises(TypeError, six.print_, x=3)
+    pytest.raises(TypeError, six.print_, end=3)
+    pytest.raises(TypeError, six.print_, sep=42)
 
 
 def test_with_metaclass():
@@ -744,7 +737,54 @@
     assert Y.__mro__ == (Y, X, object)
 
 
-@py.test.mark.skipif("sys.version_info[:2] < (3, 0)")
+@pytest.mark.skipif("sys.version_info[:2] < (2, 7)")
+def test_with_metaclass_typing():
+    try:
+        import typing
+    except ImportError:
+        pytest.skip("typing module required")
+    class Meta(type):
+        pass
+    if sys.version_info[:2] < (3, 7):
+        # Generics with custom metaclasses were broken on older versions.
+        class Meta(Meta, typing.GenericMeta):
+            pass
+    T = typing.TypeVar('T')
+    class G(six.with_metaclass(Meta, typing.Generic[T])):
+        pass
+    class GA(six.with_metaclass(abc.ABCMeta, typing.Generic[T])):
+        pass
+    assert isinstance(G, Meta)
+    assert isinstance(GA, abc.ABCMeta)
+    assert G[int] is not G[G[int]]
+    assert GA[int] is not GA[GA[int]]
+    assert G.__bases__ == (typing.Generic,)
+    assert G.__orig_bases__ == (typing.Generic[T],)
+
+
+@pytest.mark.skipif("sys.version_info[:2] < (3, 7)")
+def test_with_metaclass_pep_560():
+    class Meta(type):
+        pass
+    class A:
+        pass
+    class B:
+        pass
+    class Fake:
+        def __mro_entries__(self, bases):
+            return (A, B)
+    fake = Fake()
+    class G(six.with_metaclass(Meta, fake)):
+        pass
+    class GA(six.with_metaclass(abc.ABCMeta, fake)):
+        pass
+    assert isinstance(G, Meta)
+    assert isinstance(GA, abc.ABCMeta)
+    assert G.__bases__ == (A, B)
+    assert G.__orig_bases__ == (fake,)
+
+
+@pytest.mark.skipif("sys.version_info[:2] < (3, 0)")
 def test_with_metaclass_prepare():
     """Test that with_metaclass causes Meta.__prepare__ to be called with the correct arguments."""
 
@@ -857,7 +897,7 @@
     assert MySlots.__slots__ == ["a", "b"]
     instance = MySlots()
     instance.a = "foo"
-    py.test.raises(AttributeError, setattr, instance, "c", "baz")
+    pytest.raises(AttributeError, setattr, instance, "c", "baz")
 
     # Test a class with string for slots.
     class MyStringSlots(object):
@@ -866,8 +906,8 @@
     assert MyStringSlots.__slots__ == "ab"
     instance = MyStringSlots()
     instance.ab = "foo"
-    py.test.raises(AttributeError, setattr, instance, "a", "baz")
-    py.test.raises(AttributeError, setattr, instance, "b", "baz")
+    pytest.raises(AttributeError, setattr, instance, "a", "baz")
+    pytest.raises(AttributeError, setattr, instance, "b", "baz")
 
     class MySlotsWeakref(object):
         __slots__ = "__weakref__",
@@ -875,7 +915,27 @@
     assert type(MySlotsWeakref) is Meta
 
 
-@py.test.mark.skipif("sys.version_info[:2] < (2, 7) or sys.version_info[:2] in ((3, 0), (3, 1))")
+@pytest.mark.skipif("sys.version_info[:2] < (3, 3)")
+def test_add_metaclass_nested():
+    # Regression test for https://github.com/benjaminp/six/issues/259
+    class Meta(type):
+        pass
+
+    class A:
+        class B: pass
+
+    expected = 'test_add_metaclass_nested.<locals>.A.B'
+
+    assert A.B.__qualname__ == expected
+
+    class A:
+        @six.add_metaclass(Meta)
+        class B: pass
+
+    assert A.B.__qualname__ == expected
+
+
+@pytest.mark.skipif("sys.version_info[:2] < (2, 7) or sys.version_info[:2] in ((3, 0), (3, 1))")
 def test_assertCountEqual():
     class TestAssertCountEqual(unittest.TestCase):
         def test(self):
@@ -887,7 +947,7 @@
     TestAssertCountEqual('test').test()
 
 
-@py.test.mark.skipif("sys.version_info[:2] < (2, 7)")
+@pytest.mark.skipif("sys.version_info[:2] < (2, 7)")
 def test_assertRegex():
     class TestAssertRegex(unittest.TestCase):
         def test(self):
@@ -899,7 +959,7 @@
     TestAssertRegex('test').test()
 
 
-@py.test.mark.skipif("sys.version_info[:2] < (2, 7)")
+@pytest.mark.skipif("sys.version_info[:2] < (2, 7)")
 def test_assertRaisesRegex():
     class TestAssertRaisesRegex(unittest.TestCase):
         def test(self):
@@ -932,3 +992,61 @@
         assert str(my_test) == six.u("hello")
 
     assert getattr(six.moves.builtins, 'bytes', str)(my_test) == six.b("hello")
+
+
+class EnsureTests:
+
+    # grinning face emoji
+    UNICODE_EMOJI = six.u("\U0001F600")
+    BINARY_EMOJI = b"\xf0\x9f\x98\x80"
+
+    def test_ensure_binary_raise_type_error(self):
+        with pytest.raises(TypeError):
+            six.ensure_str(8)
+
+    def test_errors_and_encoding(self):
+        six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='ignore')
+        with pytest.raises(UnicodeEncodeError):
+            six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='strict')
+
+    def test_ensure_binary_raise(self):
+        converted_unicode = six.ensure_binary(self.UNICODE_EMOJI, encoding='utf-8', errors='strict')
+        converted_binary = six.ensure_binary(self.BINARY_EMOJI, encoding="utf-8", errors='strict')
+        if six.PY2:
+            # PY2: unicode -> str
+            assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str)
+            # PY2: str -> str
+            assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str)
+        else:
+            # PY3: str -> bytes
+            assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, bytes)
+            # PY3: bytes -> bytes
+            assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, bytes)
+
+    def test_ensure_str(self):
+        converted_unicode = six.ensure_str(self.UNICODE_EMOJI, encoding='utf-8', errors='strict')
+        converted_binary = six.ensure_str(self.BINARY_EMOJI, encoding="utf-8", errors='strict')
+        if six.PY2:
+            # PY2: unicode -> str
+            assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str)
+            # PY2: str -> str
+            assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str)
+        else:
+            # PY3: str -> str
+            assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str)
+            # PY3: bytes -> str
+            assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str)
+
+    def test_ensure_text(self):
+        converted_unicode = six.ensure_text(self.UNICODE_EMOJI, encoding='utf-8', errors='strict')
+        converted_binary = six.ensure_text(self.BINARY_EMOJI, encoding="utf-8", errors='strict')
+        if six.PY2:
+            # PY2: unicode -> unicode
+            assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode)
+            # PY2: str -> unicode
+            assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode)
+        else:
+            # PY3: str -> str
+            assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str)
+            # PY3: bytes -> str
+            assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str)