Switch to setup.cfg and pyproject.toml, supported 3.x only, dub this 1.3.9 (#21)

Entirely configuration changes, no code change.
diff --git a/.travis.yml b/.travis.yml
index c9383cc..6dc9230 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,8 +10,6 @@
   - ppc64le
 dist: focal
 install:
-  - pip install mock
-  - pip install --upgrade .
-script:
-  - python src/tests/portpicker_test.py
-  - PYTHONPATH=src python src/tests/portserver_test.py
+  - pip install --upgrade pip
+  - pip install tox-travis
+script: tox
diff --git a/ChangeLog.md b/ChangeLog.md
index 5af8f4d..8430f45 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,37 +1,45 @@
+## 1.3.9
+
+*   No portpicker or portserver code changes
+*   Fixed the portserver test on recent Python 3.x versions.
+*   Switched to setup.cfg based packaging.
+*   We no longer declare ourselves Python 2.7 or 3.3-3.5 compatible.
+
 ## 1.3.1
 
- * Fix a race condition in `pick_unused_port()` involving the free ports set.
+*   Fix a race condition in `pick_unused_port()` involving the free ports set.
 
 ## 1.3.0
 
-* Adds an optional `portserver_address` parameter to `pick_unused_port()` so
-  that callers can specify their own regardless of `os.environ`.
-* `pick_unused_port()` now raises `NoFreePortFoundError` when no available port
-  could be found rather than spinning in a loop trying forever.
-* Fall back to `socket.AF_INET` when `socket.AF_UNIX` support is not available
-  to communicate with a portserver.
+*   Adds an optional `portserver_address` parameter to `pick_unused_port()` so
+    that callers can specify their own regardless of `os.environ`.
+*   `pick_unused_port()` now raises `NoFreePortFoundError` when no available
+    port could be found rather than spinning in a loop trying forever.
+*   Fall back to `socket.AF_INET` when `socket.AF_UNIX` support is not available
+    to communicate with a portserver.
 
 ## 1.2.0
 
-* Introduced `add_reserved_port()` and `return_port()` APIs to allow ports to
-  be recycled and allow users to bring ports of their own.
+*   Introduced `add_reserved_port()` and `return_port()` APIs to allow ports to
+    be recycled and allow users to bring ports of their own.
 
 ## 1.1.1
 
-* Changed default port range to 15000-24999 to avoid ephemeral ports.
-* Portserver bugfix.
+*   Changed default port range to 15000-24999 to avoid ephemeral ports.
+*   Portserver bugfix.
 
 ## 1.1.0
 
-* Renamed portpicker APIs to use PEP8 style function names in code and docs.
-* Legacy CapWords API name compatibility is maintained (and explicitly tested).
+*   Renamed portpicker APIs to use PEP8 style function names in code and docs.
+*   Legacy CapWords API name compatibility is maintained (and explicitly
+    tested).
 
 ## 1.0.1
 
-* Code reindented to use 4 space indents and run through
-  [YAPF](https://github.com/google/yapf) for consistent style.
-* Not packaged for release.
+*   Code reindented to use 4 space indents and run through
+    [YAPF](https://github.com/google/yapf) for consistent style.
+*   Not packaged for release.
 
 ## 1.0.0
 
-* Original open source release.
+*   Original open source release.
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..fa2cd65
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,23 @@
+[build-system]
+requires = ["setuptools >= 40.9.0", "wheel"]
+build-backend = "setuptools.build_meta"
+
+[tool.tox]
+legacy_tox_ini = """
+[tox]
+envlist = py{36,37,38,39}
+isolated_build = true
+skip_missing_interpreters = true
+# minimum tox version
+minversion = 3.3.0
+[testenv]
+deps =
+    check-manifest >= 0.42
+    pytest
+commands =
+    check-manifest --ignore 'src/tests/**'
+    python -c 'from setuptools import setup; setup()' check -m -s
+    pip install --upgrade build
+    python -m build
+    py.test {posargs}
+"""
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..69d8982
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,33 @@
+# https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files
+[metadata]
+name = portpicker
+version = 1.3.9
+maintainer = Google LLC
+maintainer_email = greg@krypto.org
+license = Apache 2.0
+license_files = LICENSE
+description = A library to choose unique available network ports.
+url = https://github.com/google/python_portpicker
+long_description = Portpicker provides an API to find and return an available
+    network port for an application to bind to.  Ideally suited for use from
+    unittests or for test harnesses that launch local servers.
+classifiers =
+    Development Status :: 5 - Production/Stable
+    License :: OSI Approved :: Apache Software License
+    Intended Audience :: Developers
+    Programming Language :: Python
+    Programming Language :: Python :: 3
+    Programming Language :: Python :: 3.6
+    Programming Language :: Python :: 3.7
+    Programming Language :: Python :: 3.8
+    Programming Language :: Python :: 3.9
+    Programming Language :: Python :: Implementation :: CPython
+    Programming Language :: Python :: Implementation :: PyPy
+platforms = POSIX
+requires =
+
+[options]
+package_dir=
+    =src
+py_modules = portpicker
+scripts = src/portserver.py
diff --git a/setup.py b/setup.py
index 3cc8b60..915df37 100644
--- a/setup.py
+++ b/setup.py
@@ -1,73 +1,3 @@
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Simple distutils setup for the pure Python portpicker."""
-
-import sys
-import textwrap
-
-
+# Legacy use only, use setup.cfg and pyproject.toml for all configuration.
 import setuptools
-
-
-def main():
-    requires = []
-    scripts = []
-    py_version = sys.version_info[:2]
-    if py_version < (3, 3):
-        requires.append('mock(>=1.0)')
-    if py_version == (3, 3):
-        requires.append('asyncio(>=3.4)')
-    if py_version >= (3, 3):
-        # The example portserver implementation requires Python 3 and asyncio.
-        scripts.append('src/portserver.py')
-
-    setuptools.setup(
-        name='portpicker',
-        version='1.3.1',
-        description='A library to choose unique available network ports.',
-        long_description=textwrap.dedent("""\
-          Portpicker provides an API to find and return an available network
-          port for an application to bind to.  Ideally suited for use from
-          unittests or for test harnesses that launch local servers."""),
-        license='Apache 2.0',
-        maintainer='Google LLC',
-        maintainer_email='greg@krypto.org',
-        url='https://github.com/google/python_portpicker',
-        package_dir={'': 'src'},
-        py_modules=['portpicker'],
-        platforms=['POSIX'],
-        requires=requires,
-        scripts=scripts,
-        classifiers=
-        ['Development Status :: 5 - Production/Stable',
-         'License :: OSI Approved :: Apache Software License',
-         'Intended Audience :: Developers', 'Programming Language :: Python',
-         'Programming Language :: Python :: 2',
-         'Programming Language :: Python :: 2.7',
-         'Programming Language :: Python :: 3',
-         'Programming Language :: Python :: 3.3',
-         'Programming Language :: Python :: 3.4',
-         'Programming Language :: Python :: 3.5',
-         'Programming Language :: Python :: 3.6',
-         'Programming Language :: Python :: 3.7',
-         'Programming Language :: Python :: 3.8',
-         'Programming Language :: Python :: 3.9',
-         'Programming Language :: Python :: Implementation :: CPython',
-         'Programming Language :: Python :: Implementation :: Jython',
-         'Programming Language :: Python :: Implementation :: PyPy'])
-
-
-if __name__ == '__main__':
-    main()
+setuptools.setup()