diff --git a/.github/workflows/logging-tree-tests.yml b/.github/workflows/logging-tree-tests.yml
deleted file mode 100644
index aaab7cf..0000000
--- a/.github/workflows/logging-tree-tests.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: logging_tree tests
-
-on:
-  push:
-    branches: [ master ]
-  pull_request:
-    branches: [ master ]
-
-jobs:
-  build:
-    runs-on: ubuntu-18.04
-    strategy:
-      matrix:
-        python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8]
-
-    steps:
-    - uses: actions/checkout@v2
-    - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
-      with:
-        python-version: ${{ matrix.python-version }}
-    - name: Test with unittest
-      run: |
-        python -m unittest logging_tree.tests.test_format logging_tree.tests.test_node
diff --git a/FUNDING.yml b/FUNDING.yml
deleted file mode 100644
index 981fe19..0000000
--- a/FUNDING.yml
+++ /dev/null
@@ -1 +0,0 @@
-github: brandon-rhodes
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index dd80929..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1 +0,0 @@
-include COPYRIGHT
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..c8557d8
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,164 @@
+Metadata-Version: 1.1
+Name: logging_tree
+Version: 1.9
+Summary: Introspect and display the logger tree inside "logging"
+Home-page: https://github.com/brandon-rhodes/logging_tree
+Author: Brandon Rhodes
+Author-email: brandon@rhodesmill.org
+License: UNKNOWN
+Description: Introspection for the ``logging`` logger tree in the Standard Library.
+        
+        You can install this package with the standard ``pip`` command::
+        
+            $ pip install logging_tree
+        
+        While you can write programs that call this package's ``tree()``
+        function and examine the hierarchy of logger objects that it finds
+        inside of the Standard Library ``logging`` module, the simplest use of
+        this package for debugging is to call ``printout()`` to print the
+        loggers, filters, and handlers that your application has configured::
+        
+            >>> logging.getLogger('a')
+            >>> logging.getLogger('a.b').setLevel(logging.DEBUG)
+            >>> logging.getLogger('x.c')
+            >>> from logging_tree import printout
+            >>> printout()
+            <--""
+               Level WARNING
+               |
+               o<--"a"
+               |   Level NOTSET so inherits level WARNING
+               |   |
+               |   o<--"a.b"
+               |       Level DEBUG
+               |
+               o<--[x]
+                   |
+                   o<--"x.c"
+                       Level NOTSET so inherits level WARNING
+        
+        If you instead want to write the tree diagram to a file, stream, or
+        other file-like object, use::
+        
+            file_object.write(logging_tree.format.build_description())
+        
+        The logger tree should always print successfully, no matter how
+        complicated.  A node whose ``[name]`` is in square brackets is a "place
+        holder" that has never actually been named in a ``getLogger()`` call,
+        but was created automatically to serve as the parent of loggers further
+        down the tree.
+        
+        There are several interfaces that ``logging_tree`` supports, depending
+        on how much detail you need.
+        
+        ``logging_tree.printout(node=None)``
+        
+            Prints the current logger tree, or the tree based at the given
+            `node`, to the standard output.
+        
+        ``logging_tree.format.build_description(node=None)``
+        
+            Builds and returns the multi-line description of the current logger
+            tree, or the tree based at the given ``node``, as a single string
+            with newlines inside and a newline at the end.
+        
+        ``logging_tree.format.describe(node)``
+        
+            A generator that yields a series of lines that describe the tree
+            based at the given ``node``.  Note that the lines are returned
+            without newline terminators attached.
+        
+        ``logging_tree.tree()``
+        
+            Fetch the current tree of loggers from the ``logging`` module.
+            Returns a node, that is simply a tuple with three fields:
+        
+            | ``[0]`` the logger name (``""`` for the root logger).
+            | ``[1]`` the ``logging.Logger`` object itself.
+            | ``[2]`` a list of zero or more child nodes.
+        
+        I welcome contributions and ideas as this package matures.  You can find
+        the bug tracker at the `repository page on github
+        <https://github.com/brandon-rhodes/logging_tree>`_.  Developers can run
+        this package's tests with::
+        
+            $ python -m unittest discover logging_tree
+        
+        On older versions of Python you will instead have to install
+        ``unittest2`` and use its ``unit2`` command line tool to run the tests.
+        
+        Changelog
+        ---------
+        
+        **Version 1.9** - 2021 April 10
+            Declare compatibility with Python 3.9.  Improve how the logging
+            module's built-in ``Formatter`` class is displayed under old Python
+            versions where the ``logging`` module uses old-style classes.
+        
+        **Version 1.8.1** - 2020 January 26
+            Adjust one test to make it pass under Python 3.8, and update the
+            distribution classifiers to declare compatibility with Python
+            versions through 3.8.
+        
+        **Version 1.8** - 2018 August 5
+            Improve the output to better explain what happens if a "parent"
+            attribute has been set to None.
+        
+        **Version 1.7** - 2016 January 23
+            Detect whether each logger has the correct "parent" attribute and,
+            if not, print where its log messages are being sent instead.
+        
+        **Version 1.6** - 2015 January 8
+            Fixed a crash that would occur if a custom logging Formatter was
+            missing its format string attributes.
+        
+        **Version 1.5** - 2014 December 24
+            Handlers now display their logging level if one has been set, and
+            their custom logging formatter if one has been installed.
+        
+        **Version 1.4** - 2014 January 8
+            Thanks to a contribution from Dave Brondsema, disabled loggers are
+            now actually marked as "Disabled" to make it less of a surprise that
+            they fail to log anything.
+        
+        **Version 1.3** - 2013 October 29
+            Be explicit and display the logger level ``NOTSET`` along with the
+            effective level inherited from the logger's ancestors; and display
+            the list of ``.filters`` of a custom logging handler even though it
+            might contain custom code that ignores them.
+        
+        **Version 1.2** - 2013 January 19
+            Compatible with Python 3.3 thanks to @ralphbean.
+        
+        **Version 1.1** - 2012 February 17
+            Now compatible with 2.3 <= Python <= 3.2.
+        
+        **Version 1.0** - 2012 February 13
+            Can display the handler inside a MemoryHandler; entire public
+            interface documented; 100% test coverage.
+        
+        **Version 0.6** - 2012 February 10
+            Added a display format for every ``logging.handlers`` class.
+        
+        **Version 0.5** - 2012 February 8
+            Initial release.
+        
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 6 - Mature
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Programming Language :: Python :: 2.3
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Topic :: System :: Logging
diff --git a/README.md b/README.md
deleted file mode 100644
index 8d2e0df..0000000
--- a/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-Welcome to the `logging_tree` Python project repository!
-
-You can install this package and read its documentation
-at the project’s official entry on the Python Package Index:
-
-https://pypi.python.org/pypi/logging_tree
-
-On Debian Testing and Unstable, you can install the package for the
-system Python versions with any of the standard Debian package tools:
-
-    $ sudo apt-get install python-logging-tree
-
-The documentation is also available as the package docstring,
-kept inside of the `logging_tree/__init__.py` file here in the
-project repository.
diff --git a/debian/changelog b/debian/changelog
index 56dc28a..3386074 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+logging-tree (1.9+git20210410.1.b2d7cee-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 04 Apr 2022 20:20:21 -0000
+
 logging-tree (1.9-1) unstable; urgency=medium
 
   * New upstream release
diff --git a/release.sh b/release.sh
deleted file mode 100755
index bb920f7..0000000
--- a/release.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-set -e
-
-python3 setup.py sdist upload || true
-
-sed -i '1iimport setuptools' setup.py
-python3 setup.py bdist_wheel upload || true
-git checkout setup.py
-rm -r build logging_tree.egg-info
diff --git a/test.sh b/test.sh
deleted file mode 100755
index 5e8aaeb..0000000
--- a/test.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-#
-# This merely tests that `logging_tree` works when run directly from
-# source (and, of course, only tests the versions of Python you happen
-# to have installed with pyenv).  For a comprehensive test of whether it
-# will actually work if installed from its distribution, see `tox.ini`.
-
-for python in ~/.pyenv/versions/*/bin/python
-do
-    echo
-    echo ======================================================================
-    echo $python
-    echo ======================================================================
-    for test in logging_tree/tests/test_*.py
-    do
-        PYTHONPATH=. $python $test
-    done
-done
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index 296b78d..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-# To test against as many versions of Python as feasible, I run:
-#
-# tox --discover ~/.pyenv/versions/*/bin/python
-#
-# Unfortunately tox has lost its ability to detect older versions of
-# Python like 2.6 (much less 2.3 or 2.4); see the accompanying `test.sh`
-# script for an alternative.
-
-[tox]
-envlist = py27,py36,py37,py38,py39
-[testenv]
-commands =
-    python -m unittest discover logging_tree