diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1fef55d..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-language: python
-dist: xenial
-python:
-    - 2.7
-    - 3.6
-    - 3.7
-    - 3.8
-addons:
-    apt:
-        packages:
-            - graphviz
-install:
-    - pip install coverage coverage-python-version coveralls flake8 -e .
-before_script:
-    - make lint
-script:
-    - coverage run tests.py
-    - coverage report -m --fail-under=100
-after_success:
-    - coveralls
-notifications:
-    email: false
diff --git a/CHANGES.rst b/CHANGES.rst
index 9e7c2ba..016ef82 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -3,6 +3,14 @@ Changes
 
 .. currentmodule:: objgraph
 
+3.5.1 (unreleased)
+------------------
+
+- Add support for Python 3.9 and 3.10.
+
+- Drop support for Python 3.6.
+
+
 3.5.0 (2020-10-11)
 ------------------
 
diff --git a/Makefile b/Makefile
index 40d5c9d..c83c1ba 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ coverage:                       ##: measure test coverage
 
 .PHONY: flake8
 flake8:                         ##: check for style problems
-	flake8
+	tox -e flake8
 
 # Make sure $(VCS_DIFF_IMAGES) can work
 .PHONY: config-imgdiff
diff --git a/PKG-INFO b/PKG-INFO
index d67a9c3..120b8bc 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,422 +1,12 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: objgraph
-Version: 3.5.0
+Version: 3.5.1.dev0
 Summary: Draws Python object reference graphs with graphviz
 Home-page: https://mg.pov.lt/objgraph/
 Author: Marius Gedminas
 Author-email: marius@gedmin.as
 License: MIT
-Description: Python Object Graphs
-        ====================
-        
-        .. image:: https://travis-ci.org/mgedmin/objgraph.svg?branch=master
-           :target: https://travis-ci.org/mgedmin/objgraph
-           :alt: Build Status
-        
-        .. image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/objgraph?branch=master&svg=true
-           :target: https://ci.appveyor.com/project/mgedmin/objgraph
-           :alt: Build Status (Windows)
-        
-        .. image:: https://coveralls.io/repos/mgedmin/objgraph/badge.svg?branch=master
-           :target: https://coveralls.io/r/mgedmin/objgraph?branch=master
-           :alt: Test Coverage
-        
-        .. image:: https://readthedocs.org/projects/objgraph/badge/?version=latest
-           :target: https://readthedocs.org/projects/objgraph/?badge=latest
-           :alt: Documentation Status
-        
-        
-        ``objgraph`` is a module that lets you visually explore Python object graphs.
-        
-        You'll need `graphviz <https://www.graphviz.org/>`_ if you want to draw
-        the pretty graphs.
-        
-        I recommend `xdot <https://pypi.python.org/pypi/xdot>`_ for interactive use.
-        ``pip install xdot`` should suffice; objgraph will automatically look for it
-        in your ``PATH``.
-        
-        
-        Installation and Documentation
-        ------------------------------
-        
-        ``pip install objgraph`` or `download it from PyPI
-        <https://pypi.python.org/pypi/objgraph>`_.
-        
-        Documentation lives at https://mg.pov.lt/objgraph.
-        
-        
-        .. _history:
-        
-        History
-        -------
-        
-        I've developed a set of functions that eventually became objgraph when I
-        was hunting for memory leaks in a Python program.  The whole story -- with
-        illustrated examples -- is in this series of blog posts:
-        
-        * `Hunting memory leaks in Python
-          <https://mg.pov.lt/blog/hunting-python-memleaks.html>`_
-        * `Python object graphs
-          <https://mg.pov.lt/blog/python-object-graphs.html>`_
-        * `Object graphs with graphviz
-          <https://mg.pov.lt/blog/object-graphs-with-graphviz.html>`_
-        
-        
-        .. _devel:
-        
-        Support and Development
-        -----------------------
-        
-        The source code can be found in this Git repository:
-        https://github.com/mgedmin/objgraph.
-        
-        To check it out, use ``git clone https://github.com/mgedmin/objgraph``.
-        
-        Report bugs at https://github.com/mgedmin/objgraph/issues.
-        
-        
-        
-        Changes
-        =======
-        
-        
-        
-        3.5.0 (2020-10-11)
-        ------------------
-        
-        - Do not require ``mock`` for the test suite on Python 3; use unittest.mock
-          instead.
-        
-        - 100% test coverage for each version of Python rather than combined, using
-          ``coverage-python-version``.
-        
-        - Add the optional ``extra_node_attrs`` parameter to ``show_backrefs`` and
-          ``show_backrefs``
-        
-        - Fix IPython/Jupyter inline graph support code that would kick in even if you
-          explicitly passed a filename='foo.png' argument to
-          ``show_refs``/``show_backrefs``.  See `issue 47
-          <https://github.com/mgedmin/objgraph/issues/47>`_.
-        
-        - Add support for Python 3.8.
-        
-        - Drop support for Python 3.5.
-        
-        
-        3.4.1 (2019-04-23)
-        ------------------
-        
-        - Add support for Python 3.7.
-        
-        - Drop support for Python 3.3 and 3.4.
-        
-        
-        3.4.0 (2018-02-13)
-        ------------------
-        
-        - New functions: `get_new_ids`, `at_addrs`.
-        
-          Contributed by Justin Black in `PR 36
-          <https://github.com/mgedmin/objgraph/pull/36>`_.
-        
-        
-        3.3.0 (2017-12-28)
-        ------------------
-        
-        - New function: `growth`.
-        
-        
-        3.2.0 (2017-12-20)
-        ------------------
-        
-        - New ``filter`` argument for `typestats`, `most_common_types`,
-          `show_most_common_types`, `show_growth`.
-        
-        - Show lambda functions in a more human-friendly way.
-        
-        
-        3.1.2 (2017-11-27)
-        ------------------
-        
-        - Correct UTF-8 mojibake in the changelog and switch all links to HTTPS.
-        
-        
-        3.1.1 (2017-10-30)
-        ------------------
-        
-        - Add support for Python 3.6.
-        
-        - Replace bare ``except:`` in ``safe_repr()`` with ``except Exception:``.
-        
-        
-        3.1.0 (2016-12-07)
-        ------------------
-        
-        - Support displaying graphs inline in IPython/Jupyter notebooks (`issue 28
-          <https://github.com/mgedmin/objgraph/pull/28>`).
-        
-        
-        3.0.1 (2016-09-17)
-        ------------------
-        
-        - The ``file`` argument of `show_most_common_types` and
-          `show_growth` now defaults to ``None`` instead of ``sys.stdout``.
-          ``None`` is interpreted to be the same as ``sys.stdout``, which means
-          the right stdout will be used if you change it at runtime (which happens,
-          in doctests).
-        
-        
-        3.0.0 (2016-04-13)
-        ------------------
-        
-        - `show_most_common_types` and `show_growth` now accept a ``file``
-          argument if you want to redirect the output elsewhere.
-        
-          Fixes `issue 24 <https://github.com/mgedmin/objgraph/pull/24>`_.  Contributed
-          by "d-sun-d".
-        
-        - Don't trust ``__class__`` to be accurate and ``__name__`` to be a string.
-          Fixes errors in some convoluted corner cases when mocks are involved.
-        
-          Contributed by Andrew Shannon Brown in `PR 26
-          <https://github.com/mgedmin/objgraph/pull/26>`_.
-        
-        - Drop support for Python 2.4, 2.5, and 2.6.
-        
-        - Drop support for Python 3.1 and 3.2.
-        
-        - Add support for Python 3.5.
-        
-        
-        2.0.1 (2015-07-28)
-        ------------------
-        
-        - Avoid creating reference cycles between the stack frame and the local
-          ``objects`` variable in `by_type`, `count`, and
-          `typestats`.
-        
-          Fixes `issue 22 <https://github.com/mgedmin/objgraph/pull/22>`_.  Contributed
-          by Erik Bray.
-        
-        
-        2.0.0 (2015-04-18)
-        ------------------
-        
-        - `show_refs` and `show_backrefs` now accept a file-like object
-          (via the new ``output`` argument) as an alternative to a filename.
-        
-        - Made internal helper methods private. This includes `find_chain`,
-          `show_graph`, `obj_node_id`, `obj_label`, `quote`,
-          `long_typename`, `safe_repr`, `short_repr`,
-          `gradient`, `edge_label`, and `_program_in_path`.
-        
-        - Correctly determine the name of old-style classes in `count`,
-          `by_type`, and graph drawing functions.
-        
-          Fixes `issue 16 <https://github.com/mgedmin/objgraph/pull/16>`_.  Contributed
-          by Mike Lambert.
-        
-        
-        1.8.1 (2014-05-15)
-        ------------------
-        
-        - Do not expect file objects to have an ``encoding`` attribute.  Makes objgraph
-          compatible with Eventlet's monkey-patching.
-        
-          Fixes `issue 6 <https://github.com/mgedmin/objgraph/pull/6>`_.  Contributed
-          by Jakub Stasiak.
-        
-        
-        1.8.0 (2014-02-13)
-        ------------------
-        
-        - Moved to GitHub.
-        
-        - Python 3.4 support (`LP#1270872 <https://launchpad.net/bugs/1270872>`_).
-        
-        - New function: `is_proper_module`.
-        
-        - New ``shortnames`` argument for `typestats`, `most_common_types`,
-          `show_most_common_types`, `show_growth`, `show_refs`,
-          and `show_backrefs`.
-        
-          `count` and `by_type` accept fully-qualified type names now.
-        
-          Fixes `issue 4 <https://github.com/mgedmin/objgraph/issues/4>`_.
-        
-        
-        1.7.2 (2012-10-23)
-        ------------------
-        
-        - Bugfix: setup.py sdist was broken on Python 2.7 (UnicodeDecodeError in
-          tarfile).
-        
-        - The ``filename`` argument for `show_refs` and `show_backrefs` now
-          allows arbitrary image formats, not just PNG.  Patch by `Riccardo
-          Murri <https://launchpad.net/~rmurri>`_.
-        
-        - Temporary dot files are now named `objgraph-*.dot` instead of `tmp*.dot`.
-        
-        - Python 3.3 support: no code changes, but some tests started failing because
-          the new and improved dictionary implementation no longer holds references to
-          str objects used as dict keys.
-        
-        - Added a tox.ini for convenient multi-Python testing.
-        
-        
-        1.7.1 (2011-12-11)
-        ------------------
-        
-        - Bugfix: non-ASCII characters in object representations would break graph
-          generation on Python 3.x, in some locales (e.g. with LC_ALL=C).  Reported and
-          fixed by `Stefano Rivera <https://launchpad.net/~stefanor>`_.
-        
-        - Bugfix: setup.py was broken on Python 3.x
-        
-        - Bugfix: dot.exe/xdot.exe were not found on Windows (`LP#767239
-          <https://launchpad.net/bugs/767239>`_).
-        
-        - Documentation updates: document the forgotten `find_ref_chain`,
-          update `show_chain` prototype.
-        
-        
-        1.7.0 (2011-03-11)
-        ------------------
-        
-        - New function: `find_ref_chain`.
-        
-        - New ``backrefs`` argument for `show_chain`.
-        
-        - New function: `get_leaking_objects`, based on `a blog post by
-          Kristján Valur
-          <https://cosmicpercolator.com/2010/12/08/finding-c-reference-leaks-using-the-gc-module/>`_.
-        
-        - New ``objects`` argument for `count`, `typestats`,
-          `most_common_types`, `show_most_common_types`, and
-          `by_type`.
-        
-        - Edges pointing to function attributes such as __defaults__ or __globals__
-          are now labeled.
-        
-        - Edge labels that are not simple strings now show the type.
-        
-        - Bugfix: '\0' and other unsafe characters used in a dictionary key could
-          break graph generation.
-        
-        - Bugfix: show_refs(..., filename='graph.dot') would then go to complain
-          about unrecognized file types and then produce a png.
-        
-        
-        1.6.0 (2010-12-18)
-        ------------------
-        
-        - Python 3 support, thanks to Stefano Rivera (fixes `LP#687601
-          <https://launchpad.net/bugs/687601>`_).
-        
-        - Removed weird weakref special-casing.
-        
-        
-        1.5.1 (2010-12-09)
-        ------------------
-        
-        - Avoid test failures in uncollectable-garbage.txt (fixes `LP#686731
-          <https://launchpad.net/bugs/686731>`_).
-        
-        - Added HACKING.txt (later renamed to HACKING.rst).
-        
-        
-        1.5.0 (2010-12-05)
-        ------------------
-        
-        - Show frame objects as well (fixes `LP#361704
-          <https://launchpad.net/bugs/361704>`_).
-        
-        - New functions: `show_growth`, `show_chain`.
-        
-        - `find_backref_chain` returns ``[obj]`` instead of ``None`` when a chain
-          could not be found.  This makes ``show_chain(find_backref_chain(...), ...)``
-          not break.
-        
-        - Show how many references were skipped from the output of
-          `show_refs`/`show_backrefs` by specifying ``too_many``.
-        
-        - Make `show_refs` descend into modules.
-        
-        - Do not highlight classes that define a ``__del__``, highlight only instances of
-          those classes.
-        
-        - Option to show reference counts in `show_refs`/`show_backrefs`.
-        
-        - Add `Sphinx <https://pypi.python.org/pypi/Sphinx>`_ documentation and a PyPI
-          long description.
-        
-        
-        1.4.0 (2010-11-03)
-        ------------------
-        
-        - Compatibility with Python 2.4 and 2.5 (``tempfile.NamedTemporaryFile`` has no
-          ``delete`` argument).
-        
-        - New function: `most_common_types`.
-        
-        
-        1.3.1 (2010-07-17)
-        ------------------
-        
-        - Rebuild an sdist with no missing files (fixes `LP#606604
-          <https://launchpad.net/bugs/606604>`_).
-        
-        - Added MANIFEST.in and a Makefile to check that setup.py sdist generates
-          source distributions with no files missing.
-        
-        
-        1.3 (2010-07-13)
-        ----------------
-        
-        - Highlight objects with a ``__del__`` method.
-        
-        - Fixes `LP#483411 <https://launchpad.net/bugs/483411>`_: suggest always passing
-          ``[obj]`` to `show_refs`, `show_backrefs`, since obj might be a
-          list/tuple.
-        
-        - Fixes `LP#514422 <https://launchpad.net/bugs/514422>`_: `show_refs`,
-          `show_backrefs` don't create files in the current working directory any
-          more.  Instead they accept a filename argument, which can be a .dot file or a
-          .png file.  If None or not specified, those functions will try to spawn xdot
-          as before.
-        
-        - New extra_info argument to graph-generating functions (patch by Thouis Jones,
-          `LP#558914 <https://launchpad.net/bugs/558914>`_).
-        
-        - setup.py should work with distutils now (`LP#604430
-          <https://launchpad.net/bugs/604430>`_, thanks to Randy Heydon).
-        
-        
-        1.2 (2009-03-25)
-        ----------------
-        
-        - Project website, public source repository, uploaded to PyPI.
-        
-        - No code changes.
-        
-        
-        1.1 (2008-09-10)
-        ----------------
-        
-        - New function: `show_refs` for showing forward references.
-        
-        - New functions: `typestats` and `show_most_common_types`.
-        
-        - Object boxes are less crammed with useless information (such as IDs).
-        
-        - Spawns `xdot <https://pypi.python.org/pypi/xdot>`_ if it is available.
-        
-        
-        1.0 (2008-06-14)
-        ----------------
-        
-        - First public release.
-        
+Project-URL: Source, https://github.com/mgedmin/objgraph
 Keywords: object graph visualization graphviz garbage collection
 Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
@@ -424,6 +14,431 @@ Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
-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: Programming Language :: Python :: 3.10
+Description-Content-Type: text/x-rst
+Provides-Extra: test
+License-File: LICENSE
+
+Python Object Graphs
+====================
+
+.. image:: https://github.com/mgedmin/objgraph/workflows/build/badge.svg?branch=master
+    :target: https://github.com/mgedmin/objgraph/actions
+   :alt: Build Status
+
+.. image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/objgraph?branch=master&svg=true
+   :target: https://ci.appveyor.com/project/mgedmin/objgraph
+   :alt: Build Status (Windows)
+
+.. image:: https://coveralls.io/repos/mgedmin/objgraph/badge.svg?branch=master
+   :target: https://coveralls.io/r/mgedmin/objgraph?branch=master
+   :alt: Test Coverage
+
+.. image:: https://readthedocs.org/projects/objgraph/badge/?version=latest
+   :target: https://readthedocs.org/projects/objgraph/?badge=latest
+   :alt: Documentation Status
+
+
+``objgraph`` is a module that lets you visually explore Python object graphs.
+
+You'll need `graphviz <https://www.graphviz.org/>`_ if you want to draw
+the pretty graphs.
+
+I recommend `xdot <https://pypi.python.org/pypi/xdot>`_ for interactive use.
+``pip install xdot`` should suffice; objgraph will automatically look for it
+in your ``PATH``.
+
+
+Installation and Documentation
+------------------------------
+
+``pip install objgraph`` or `download it from PyPI
+<https://pypi.python.org/pypi/objgraph>`_.
+
+Documentation lives at https://mg.pov.lt/objgraph.
+
+
+.. _history:
+
+History
+-------
+
+I've developed a set of functions that eventually became objgraph when I
+was hunting for memory leaks in a Python program.  The whole story -- with
+illustrated examples -- is in this series of blog posts:
+
+* `Hunting memory leaks in Python
+  <https://mg.pov.lt/blog/hunting-python-memleaks.html>`_
+* `Python object graphs
+  <https://mg.pov.lt/blog/python-object-graphs.html>`_
+* `Object graphs with graphviz
+  <https://mg.pov.lt/blog/object-graphs-with-graphviz.html>`_
+
+
+.. _devel:
+
+Support and Development
+-----------------------
+
+The source code can be found in this Git repository:
+https://github.com/mgedmin/objgraph.
+
+To check it out, use ``git clone https://github.com/mgedmin/objgraph``.
+
+Report bugs at https://github.com/mgedmin/objgraph/issues.
+
+
+
+Changes
+=======
+
+
+
+3.5.1 (unreleased)
+------------------
+
+- Add support for Python 3.9 and 3.10.
+
+- Drop support for Python 3.6.
+
+
+3.5.0 (2020-10-11)
+------------------
+
+- Do not require ``mock`` for the test suite on Python 3; use unittest.mock
+  instead.
+
+- 100% test coverage for each version of Python rather than combined, using
+  ``coverage-python-version``.
+
+- Add the optional ``extra_node_attrs`` parameter to ``show_backrefs`` and
+  ``show_backrefs``
+
+- Fix IPython/Jupyter inline graph support code that would kick in even if you
+  explicitly passed a filename='foo.png' argument to
+  ``show_refs``/``show_backrefs``.  See `issue 47
+  <https://github.com/mgedmin/objgraph/issues/47>`_.
+
+- Add support for Python 3.8.
+
+- Drop support for Python 3.5.
+
+
+3.4.1 (2019-04-23)
+------------------
+
+- Add support for Python 3.7.
+
+- Drop support for Python 3.3 and 3.4.
+
+
+3.4.0 (2018-02-13)
+------------------
+
+- New functions: `get_new_ids`, `at_addrs`.
+
+  Contributed by Justin Black in `PR 36
+  <https://github.com/mgedmin/objgraph/pull/36>`_.
+
+
+3.3.0 (2017-12-28)
+------------------
+
+- New function: `growth`.
+
+
+3.2.0 (2017-12-20)
+------------------
+
+- New ``filter`` argument for `typestats`, `most_common_types`,
+  `show_most_common_types`, `show_growth`.
+
+- Show lambda functions in a more human-friendly way.
+
+
+3.1.2 (2017-11-27)
+------------------
+
+- Correct UTF-8 mojibake in the changelog and switch all links to HTTPS.
+
+
+3.1.1 (2017-10-30)
+------------------
+
+- Add support for Python 3.6.
+
+- Replace bare ``except:`` in ``safe_repr()`` with ``except Exception:``.
+
+
+3.1.0 (2016-12-07)
+------------------
+
+- Support displaying graphs inline in IPython/Jupyter notebooks (`issue 28
+  <https://github.com/mgedmin/objgraph/pull/28>`).
+
+
+3.0.1 (2016-09-17)
+------------------
+
+- The ``file`` argument of `show_most_common_types` and
+  `show_growth` now defaults to ``None`` instead of ``sys.stdout``.
+  ``None`` is interpreted to be the same as ``sys.stdout``, which means
+  the right stdout will be used if you change it at runtime (which happens,
+  in doctests).
+
+
+3.0.0 (2016-04-13)
+------------------
+
+- `show_most_common_types` and `show_growth` now accept a ``file``
+  argument if you want to redirect the output elsewhere.
+
+  Fixes `issue 24 <https://github.com/mgedmin/objgraph/pull/24>`_.  Contributed
+  by "d-sun-d".
+
+- Don't trust ``__class__`` to be accurate and ``__name__`` to be a string.
+  Fixes errors in some convoluted corner cases when mocks are involved.
+
+  Contributed by Andrew Shannon Brown in `PR 26
+  <https://github.com/mgedmin/objgraph/pull/26>`_.
+
+- Drop support for Python 2.4, 2.5, and 2.6.
+
+- Drop support for Python 3.1 and 3.2.
+
+- Add support for Python 3.5.
+
+
+2.0.1 (2015-07-28)
+------------------
+
+- Avoid creating reference cycles between the stack frame and the local
+  ``objects`` variable in `by_type`, `count`, and
+  `typestats`.
+
+  Fixes `issue 22 <https://github.com/mgedmin/objgraph/pull/22>`_.  Contributed
+  by Erik Bray.
+
+
+2.0.0 (2015-04-18)
+------------------
+
+- `show_refs` and `show_backrefs` now accept a file-like object
+  (via the new ``output`` argument) as an alternative to a filename.
+
+- Made internal helper methods private. This includes `find_chain`,
+  `show_graph`, `obj_node_id`, `obj_label`, `quote`,
+  `long_typename`, `safe_repr`, `short_repr`,
+  `gradient`, `edge_label`, and `_program_in_path`.
+
+- Correctly determine the name of old-style classes in `count`,
+  `by_type`, and graph drawing functions.
+
+  Fixes `issue 16 <https://github.com/mgedmin/objgraph/pull/16>`_.  Contributed
+  by Mike Lambert.
+
+
+1.8.1 (2014-05-15)
+------------------
+
+- Do not expect file objects to have an ``encoding`` attribute.  Makes objgraph
+  compatible with Eventlet's monkey-patching.
+
+  Fixes `issue 6 <https://github.com/mgedmin/objgraph/pull/6>`_.  Contributed
+  by Jakub Stasiak.
+
+
+1.8.0 (2014-02-13)
+------------------
+
+- Moved to GitHub.
+
+- Python 3.4 support (`LP#1270872 <https://launchpad.net/bugs/1270872>`_).
+
+- New function: `is_proper_module`.
+
+- New ``shortnames`` argument for `typestats`, `most_common_types`,
+  `show_most_common_types`, `show_growth`, `show_refs`,
+  and `show_backrefs`.
+
+  `count` and `by_type` accept fully-qualified type names now.
+
+  Fixes `issue 4 <https://github.com/mgedmin/objgraph/issues/4>`_.
+
+
+1.7.2 (2012-10-23)
+------------------
+
+- Bugfix: setup.py sdist was broken on Python 2.7 (UnicodeDecodeError in
+  tarfile).
+
+- The ``filename`` argument for `show_refs` and `show_backrefs` now
+  allows arbitrary image formats, not just PNG.  Patch by `Riccardo
+  Murri <https://launchpad.net/~rmurri>`_.
+
+- Temporary dot files are now named `objgraph-*.dot` instead of `tmp*.dot`.
+
+- Python 3.3 support: no code changes, but some tests started failing because
+  the new and improved dictionary implementation no longer holds references to
+  str objects used as dict keys.
+
+- Added a tox.ini for convenient multi-Python testing.
+
+
+1.7.1 (2011-12-11)
+------------------
+
+- Bugfix: non-ASCII characters in object representations would break graph
+  generation on Python 3.x, in some locales (e.g. with LC_ALL=C).  Reported and
+  fixed by `Stefano Rivera <https://launchpad.net/~stefanor>`_.
+
+- Bugfix: setup.py was broken on Python 3.x
+
+- Bugfix: dot.exe/xdot.exe were not found on Windows (`LP#767239
+  <https://launchpad.net/bugs/767239>`_).
+
+- Documentation updates: document the forgotten `find_ref_chain`,
+  update `show_chain` prototype.
+
+
+1.7.0 (2011-03-11)
+------------------
+
+- New function: `find_ref_chain`.
+
+- New ``backrefs`` argument for `show_chain`.
+
+- New function: `get_leaking_objects`, based on `a blog post by
+  Kristján Valur
+  <https://cosmicpercolator.com/2010/12/08/finding-c-reference-leaks-using-the-gc-module/>`_.
+
+- New ``objects`` argument for `count`, `typestats`,
+  `most_common_types`, `show_most_common_types`, and
+  `by_type`.
+
+- Edges pointing to function attributes such as __defaults__ or __globals__
+  are now labeled.
+
+- Edge labels that are not simple strings now show the type.
+
+- Bugfix: '\0' and other unsafe characters used in a dictionary key could
+  break graph generation.
+
+- Bugfix: show_refs(..., filename='graph.dot') would then go to complain
+  about unrecognized file types and then produce a png.
+
+
+1.6.0 (2010-12-18)
+------------------
+
+- Python 3 support, thanks to Stefano Rivera (fixes `LP#687601
+  <https://launchpad.net/bugs/687601>`_).
+
+- Removed weird weakref special-casing.
+
+
+1.5.1 (2010-12-09)
+------------------
+
+- Avoid test failures in uncollectable-garbage.txt (fixes `LP#686731
+  <https://launchpad.net/bugs/686731>`_).
+
+- Added HACKING.txt (later renamed to HACKING.rst).
+
+
+1.5.0 (2010-12-05)
+------------------
+
+- Show frame objects as well (fixes `LP#361704
+  <https://launchpad.net/bugs/361704>`_).
+
+- New functions: `show_growth`, `show_chain`.
+
+- `find_backref_chain` returns ``[obj]`` instead of ``None`` when a chain
+  could not be found.  This makes ``show_chain(find_backref_chain(...), ...)``
+  not break.
+
+- Show how many references were skipped from the output of
+  `show_refs`/`show_backrefs` by specifying ``too_many``.
+
+- Make `show_refs` descend into modules.
+
+- Do not highlight classes that define a ``__del__``, highlight only instances of
+  those classes.
+
+- Option to show reference counts in `show_refs`/`show_backrefs`.
+
+- Add `Sphinx <https://pypi.python.org/pypi/Sphinx>`_ documentation and a PyPI
+  long description.
+
+
+1.4.0 (2010-11-03)
+------------------
+
+- Compatibility with Python 2.4 and 2.5 (``tempfile.NamedTemporaryFile`` has no
+  ``delete`` argument).
+
+- New function: `most_common_types`.
+
+
+1.3.1 (2010-07-17)
+------------------
+
+- Rebuild an sdist with no missing files (fixes `LP#606604
+  <https://launchpad.net/bugs/606604>`_).
+
+- Added MANIFEST.in and a Makefile to check that setup.py sdist generates
+  source distributions with no files missing.
+
+
+1.3 (2010-07-13)
+----------------
+
+- Highlight objects with a ``__del__`` method.
+
+- Fixes `LP#483411 <https://launchpad.net/bugs/483411>`_: suggest always passing
+  ``[obj]`` to `show_refs`, `show_backrefs`, since obj might be a
+  list/tuple.
+
+- Fixes `LP#514422 <https://launchpad.net/bugs/514422>`_: `show_refs`,
+  `show_backrefs` don't create files in the current working directory any
+  more.  Instead they accept a filename argument, which can be a .dot file or a
+  .png file.  If None or not specified, those functions will try to spawn xdot
+  as before.
+
+- New extra_info argument to graph-generating functions (patch by Thouis Jones,
+  `LP#558914 <https://launchpad.net/bugs/558914>`_).
+
+- setup.py should work with distutils now (`LP#604430
+  <https://launchpad.net/bugs/604430>`_, thanks to Randy Heydon).
+
+
+1.2 (2009-03-25)
+----------------
+
+- Project website, public source repository, uploaded to PyPI.
+
+- No code changes.
+
+
+1.1 (2008-09-10)
+----------------
+
+- New function: `show_refs` for showing forward references.
+
+- New functions: `typestats` and `show_most_common_types`.
+
+- Object boxes are less crammed with useless information (such as IDs).
+
+- Spawns `xdot <https://pypi.python.org/pypi/xdot>`_ if it is available.
+
+
+1.0 (2008-06-14)
+----------------
+
+- First public release.
+
+
diff --git a/README.rst b/README.rst
index bd0b82b..d85253b 100644
--- a/README.rst
+++ b/README.rst
@@ -1,8 +1,8 @@
 Python Object Graphs
 ====================
 
-.. image:: https://travis-ci.org/mgedmin/objgraph.svg?branch=master
-   :target: https://travis-ci.org/mgedmin/objgraph
+.. image:: https://github.com/mgedmin/objgraph/workflows/build/badge.svg?branch=master
+    :target: https://github.com/mgedmin/objgraph/actions
    :alt: Build Status
 
 .. image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/objgraph?branch=master&svg=true
diff --git a/appveyor.yml b/appveyor.yml
index bbc42fc..f95698d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,9 +5,10 @@ environment:
     # https://www.appveyor.com/docs/installed-software#python lists available
     # versions
     - PYTHON: "C:\\Python27"
-    - PYTHON: "C:\\Python36"
     - PYTHON: "C:\\Python37"
     - PYTHON: "C:\\Python38"
+    - PYTHON: "C:\\Python39"
+    - PYTHON: "C:\\Python310"
 
 init:
   - "echo %PYTHON%"
@@ -23,8 +24,7 @@ install:
   - python --version
   - pip install -U virtualenv  # upgrade pip in tox's virtualenvs
   - pip install tox
-  - choco install graphviz
-  - "set PATH=c:\\Program Files (x86)\\graphviz2.38\\bin;%PATH%"
+  - choco install graphviz --version=2.38.0.20190211
   - dot -V
 
 build: off
diff --git a/debian/changelog b/debian/changelog
index 853d94e..1b4765e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,13 @@
-objgraph (3.5.0-5) UNRELEASED; urgency=medium
+objgraph (3.5.0+git20220317.1.f1ec646-1) UNRELEASED; urgency=medium
 
   * Remove constraints unnecessary since buster:
     + Build-Depends: Drop versioned constraint on python3-all and
       python3-sphinx.
+  * New upstream snapshot.
+  * Drop patch remove-external-images, present upstream.
+  * Drop patch py3-sphinx, present upstream.
 
- -- Debian Janitor <janitor@jelmer.uk>  Fri, 24 Sep 2021 09:23:33 -0000
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 21 Mar 2022 10:21:54 -0000
 
 objgraph (3.5.0-4) unstable; urgency=medium
 
diff --git a/debian/patches/no-graphviz b/debian/patches/no-graphviz
index 1dabefe..a6e8c06 100644
--- a/debian/patches/no-graphviz
+++ b/debian/patches/no-graphviz
@@ -9,15 +9,15 @@ Forwarded: not-needed
  setup.py | 1 -
  1 file changed, 1 deletion(-)
 
-diff --git a/setup.py b/setup.py
-index f28ca18..0325d00 100755
---- a/setup.py
-+++ b/setup.py
-@@ -80,7 +80,6 @@ setup(
+Index: objgraph/setup.py
+===================================================================
+--- objgraph.orig/setup.py
++++ objgraph/setup.py
+@@ -85,7 +85,6 @@ setup(
      keywords='object graph visualization graphviz garbage collection',
      py_modules=['objgraph'],
      install_requires=[
 -        'graphviz',  # just for ipython support currently
      ],
-     tests_require=['mock;python_version=="2.7"'],
-     test_suite='tests.test_suite',
+     extras_require={
+         'test': [
diff --git a/debian/patches/py3-sphinx b/debian/patches/py3-sphinx
deleted file mode 100644
index 47e1c5d..0000000
--- a/debian/patches/py3-sphinx
+++ /dev/null
@@ -1,58 +0,0 @@
-From: Marius Gedminas <marius@gedmin.as>
-Date: Fri, 22 Oct 2021 10:33:44 -0700
-Subject: Extract version from objgraph.py without py2 exec
-
-Origin: upstream, https://github.com/mgedmin/objgraph/commit/e96d904f09278ef1a32eb666fb1db7d0d3c778db
----
- docs/conf.py | 23 +++++++++++++++++++----
- 1 file changed, 19 insertions(+), 4 deletions(-)
-
-diff --git a/docs/conf.py b/docs/conf.py
-index bd7c083..85c5a5d 100644
---- a/docs/conf.py
-+++ b/docs/conf.py
-@@ -11,25 +11,40 @@
- # All configuration values have a default; values that are commented out
- # serve to show the default.
- 
--import sys, os
-+import io
-+import os
-+import re
-+import sys
- 
- # If extensions (or modules to document with autodoc) are in another directory,
- # add these directories to sys.path here. If the directory is relative to the
- # documentation root, use os.path.abspath to make it absolute, like shown here.
- sys.path.append(os.path.abspath('..'))
- 
-+
- def relative(filename):
-     here = os.path.dirname('__file__')
-     return os.path.join(here, filename)
- 
-+
-+def read(filename):
-+    with io.open(relative(filename), encoding='UTF-8') as f:
-+        return f.read()
-+
-+
- def get_version():
--    d = {}
--    exec open(relative('../objgraph.py')).read() in d
--    return d['__version__']
-+    r = re.compile('''^__version__ = ["'](.+)["']$''')
-+    for line in read('../objgraph.py').splitlines():
-+        m = r.match(line)
-+        if m:
-+            return m.group(1)
-+    raise AssertionError('Could not determine version number from objgraph.py')
-+
- 
- def get_short_version():
-     return '.'.join(get_version().split('.')[:2])
- 
-+
- # -- General configuration -----------------------------------------------------
- 
- # Add any Sphinx extension module names here, as strings. They can be extensions
diff --git a/debian/patches/remove-external-images b/debian/patches/remove-external-images
deleted file mode 100644
index 7a4d1ec..0000000
--- a/debian/patches/remove-external-images
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Stefano Rivera <stefanor@debian.org>
-Date: Thu, 8 Oct 2015 10:04:07 -0700
-Subject: Remove references to external images from docs
-
- Fetching resources from remote websites when viewing local documentation could
- breach privacy.
- It's fairly unlikely that anyone viewing this documentation cares about the
- current CI status.
-Forwarded: not-needed
----
- README.rst | 17 -----------------
- 1 file changed, 17 deletions(-)
-
-diff --git a/README.rst b/README.rst
-index bd0b82b..ea92544 100644
---- a/README.rst
-+++ b/README.rst
-@@ -1,23 +1,6 @@
- Python Object Graphs
- ====================
- 
--.. image:: https://travis-ci.org/mgedmin/objgraph.svg?branch=master
--   :target: https://travis-ci.org/mgedmin/objgraph
--   :alt: Build Status
--
--.. image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/objgraph?branch=master&svg=true
--   :target: https://ci.appveyor.com/project/mgedmin/objgraph
--   :alt: Build Status (Windows)
--
--.. image:: https://coveralls.io/repos/mgedmin/objgraph/badge.svg?branch=master
--   :target: https://coveralls.io/r/mgedmin/objgraph?branch=master
--   :alt: Test Coverage
--
--.. image:: https://readthedocs.org/projects/objgraph/badge/?version=latest
--   :target: https://readthedocs.org/projects/objgraph/?badge=latest
--   :alt: Documentation Status
--
--
- ``objgraph`` is a module that lets you visually explore Python object graphs.
- 
- You'll need `graphviz <https://www.graphviz.org/>`_ if you want to draw
diff --git a/debian/patches/series b/debian/patches/series
index e7aad04..e894e2b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1 @@
-remove-external-images
 no-graphviz
-py3-sphinx
diff --git a/docs/conf.py b/docs/conf.py
index bd7c083..85c5a5d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -11,25 +11,40 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys, os
+import io
+import os
+import re
+import sys
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 sys.path.append(os.path.abspath('..'))
 
+
 def relative(filename):
     here = os.path.dirname('__file__')
     return os.path.join(here, filename)
 
+
+def read(filename):
+    with io.open(relative(filename), encoding='UTF-8') as f:
+        return f.read()
+
+
 def get_version():
-    d = {}
-    exec open(relative('../objgraph.py')).read() in d
-    return d['__version__']
+    r = re.compile('''^__version__ = ["'](.+)["']$''')
+    for line in read('../objgraph.py').splitlines():
+        m = r.match(line)
+        if m:
+            return m.group(1)
+    raise AssertionError('Could not determine version number from objgraph.py')
+
 
 def get_short_version():
     return '.'.join(get_version().split('.')[:2])
 
+
 # -- General configuration -----------------------------------------------------
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
diff --git a/objgraph.egg-info/PKG-INFO b/objgraph.egg-info/PKG-INFO
index d67a9c3..120b8bc 100644
--- a/objgraph.egg-info/PKG-INFO
+++ b/objgraph.egg-info/PKG-INFO
@@ -1,422 +1,12 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: objgraph
-Version: 3.5.0
+Version: 3.5.1.dev0
 Summary: Draws Python object reference graphs with graphviz
 Home-page: https://mg.pov.lt/objgraph/
 Author: Marius Gedminas
 Author-email: marius@gedmin.as
 License: MIT
-Description: Python Object Graphs
-        ====================
-        
-        .. image:: https://travis-ci.org/mgedmin/objgraph.svg?branch=master
-           :target: https://travis-ci.org/mgedmin/objgraph
-           :alt: Build Status
-        
-        .. image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/objgraph?branch=master&svg=true
-           :target: https://ci.appveyor.com/project/mgedmin/objgraph
-           :alt: Build Status (Windows)
-        
-        .. image:: https://coveralls.io/repos/mgedmin/objgraph/badge.svg?branch=master
-           :target: https://coveralls.io/r/mgedmin/objgraph?branch=master
-           :alt: Test Coverage
-        
-        .. image:: https://readthedocs.org/projects/objgraph/badge/?version=latest
-           :target: https://readthedocs.org/projects/objgraph/?badge=latest
-           :alt: Documentation Status
-        
-        
-        ``objgraph`` is a module that lets you visually explore Python object graphs.
-        
-        You'll need `graphviz <https://www.graphviz.org/>`_ if you want to draw
-        the pretty graphs.
-        
-        I recommend `xdot <https://pypi.python.org/pypi/xdot>`_ for interactive use.
-        ``pip install xdot`` should suffice; objgraph will automatically look for it
-        in your ``PATH``.
-        
-        
-        Installation and Documentation
-        ------------------------------
-        
-        ``pip install objgraph`` or `download it from PyPI
-        <https://pypi.python.org/pypi/objgraph>`_.
-        
-        Documentation lives at https://mg.pov.lt/objgraph.
-        
-        
-        .. _history:
-        
-        History
-        -------
-        
-        I've developed a set of functions that eventually became objgraph when I
-        was hunting for memory leaks in a Python program.  The whole story -- with
-        illustrated examples -- is in this series of blog posts:
-        
-        * `Hunting memory leaks in Python
-          <https://mg.pov.lt/blog/hunting-python-memleaks.html>`_
-        * `Python object graphs
-          <https://mg.pov.lt/blog/python-object-graphs.html>`_
-        * `Object graphs with graphviz
-          <https://mg.pov.lt/blog/object-graphs-with-graphviz.html>`_
-        
-        
-        .. _devel:
-        
-        Support and Development
-        -----------------------
-        
-        The source code can be found in this Git repository:
-        https://github.com/mgedmin/objgraph.
-        
-        To check it out, use ``git clone https://github.com/mgedmin/objgraph``.
-        
-        Report bugs at https://github.com/mgedmin/objgraph/issues.
-        
-        
-        
-        Changes
-        =======
-        
-        
-        
-        3.5.0 (2020-10-11)
-        ------------------
-        
-        - Do not require ``mock`` for the test suite on Python 3; use unittest.mock
-          instead.
-        
-        - 100% test coverage for each version of Python rather than combined, using
-          ``coverage-python-version``.
-        
-        - Add the optional ``extra_node_attrs`` parameter to ``show_backrefs`` and
-          ``show_backrefs``
-        
-        - Fix IPython/Jupyter inline graph support code that would kick in even if you
-          explicitly passed a filename='foo.png' argument to
-          ``show_refs``/``show_backrefs``.  See `issue 47
-          <https://github.com/mgedmin/objgraph/issues/47>`_.
-        
-        - Add support for Python 3.8.
-        
-        - Drop support for Python 3.5.
-        
-        
-        3.4.1 (2019-04-23)
-        ------------------
-        
-        - Add support for Python 3.7.
-        
-        - Drop support for Python 3.3 and 3.4.
-        
-        
-        3.4.0 (2018-02-13)
-        ------------------
-        
-        - New functions: `get_new_ids`, `at_addrs`.
-        
-          Contributed by Justin Black in `PR 36
-          <https://github.com/mgedmin/objgraph/pull/36>`_.
-        
-        
-        3.3.0 (2017-12-28)
-        ------------------
-        
-        - New function: `growth`.
-        
-        
-        3.2.0 (2017-12-20)
-        ------------------
-        
-        - New ``filter`` argument for `typestats`, `most_common_types`,
-          `show_most_common_types`, `show_growth`.
-        
-        - Show lambda functions in a more human-friendly way.
-        
-        
-        3.1.2 (2017-11-27)
-        ------------------
-        
-        - Correct UTF-8 mojibake in the changelog and switch all links to HTTPS.
-        
-        
-        3.1.1 (2017-10-30)
-        ------------------
-        
-        - Add support for Python 3.6.
-        
-        - Replace bare ``except:`` in ``safe_repr()`` with ``except Exception:``.
-        
-        
-        3.1.0 (2016-12-07)
-        ------------------
-        
-        - Support displaying graphs inline in IPython/Jupyter notebooks (`issue 28
-          <https://github.com/mgedmin/objgraph/pull/28>`).
-        
-        
-        3.0.1 (2016-09-17)
-        ------------------
-        
-        - The ``file`` argument of `show_most_common_types` and
-          `show_growth` now defaults to ``None`` instead of ``sys.stdout``.
-          ``None`` is interpreted to be the same as ``sys.stdout``, which means
-          the right stdout will be used if you change it at runtime (which happens,
-          in doctests).
-        
-        
-        3.0.0 (2016-04-13)
-        ------------------
-        
-        - `show_most_common_types` and `show_growth` now accept a ``file``
-          argument if you want to redirect the output elsewhere.
-        
-          Fixes `issue 24 <https://github.com/mgedmin/objgraph/pull/24>`_.  Contributed
-          by "d-sun-d".
-        
-        - Don't trust ``__class__`` to be accurate and ``__name__`` to be a string.
-          Fixes errors in some convoluted corner cases when mocks are involved.
-        
-          Contributed by Andrew Shannon Brown in `PR 26
-          <https://github.com/mgedmin/objgraph/pull/26>`_.
-        
-        - Drop support for Python 2.4, 2.5, and 2.6.
-        
-        - Drop support for Python 3.1 and 3.2.
-        
-        - Add support for Python 3.5.
-        
-        
-        2.0.1 (2015-07-28)
-        ------------------
-        
-        - Avoid creating reference cycles between the stack frame and the local
-          ``objects`` variable in `by_type`, `count`, and
-          `typestats`.
-        
-          Fixes `issue 22 <https://github.com/mgedmin/objgraph/pull/22>`_.  Contributed
-          by Erik Bray.
-        
-        
-        2.0.0 (2015-04-18)
-        ------------------
-        
-        - `show_refs` and `show_backrefs` now accept a file-like object
-          (via the new ``output`` argument) as an alternative to a filename.
-        
-        - Made internal helper methods private. This includes `find_chain`,
-          `show_graph`, `obj_node_id`, `obj_label`, `quote`,
-          `long_typename`, `safe_repr`, `short_repr`,
-          `gradient`, `edge_label`, and `_program_in_path`.
-        
-        - Correctly determine the name of old-style classes in `count`,
-          `by_type`, and graph drawing functions.
-        
-          Fixes `issue 16 <https://github.com/mgedmin/objgraph/pull/16>`_.  Contributed
-          by Mike Lambert.
-        
-        
-        1.8.1 (2014-05-15)
-        ------------------
-        
-        - Do not expect file objects to have an ``encoding`` attribute.  Makes objgraph
-          compatible with Eventlet's monkey-patching.
-        
-          Fixes `issue 6 <https://github.com/mgedmin/objgraph/pull/6>`_.  Contributed
-          by Jakub Stasiak.
-        
-        
-        1.8.0 (2014-02-13)
-        ------------------
-        
-        - Moved to GitHub.
-        
-        - Python 3.4 support (`LP#1270872 <https://launchpad.net/bugs/1270872>`_).
-        
-        - New function: `is_proper_module`.
-        
-        - New ``shortnames`` argument for `typestats`, `most_common_types`,
-          `show_most_common_types`, `show_growth`, `show_refs`,
-          and `show_backrefs`.
-        
-          `count` and `by_type` accept fully-qualified type names now.
-        
-          Fixes `issue 4 <https://github.com/mgedmin/objgraph/issues/4>`_.
-        
-        
-        1.7.2 (2012-10-23)
-        ------------------
-        
-        - Bugfix: setup.py sdist was broken on Python 2.7 (UnicodeDecodeError in
-          tarfile).
-        
-        - The ``filename`` argument for `show_refs` and `show_backrefs` now
-          allows arbitrary image formats, not just PNG.  Patch by `Riccardo
-          Murri <https://launchpad.net/~rmurri>`_.
-        
-        - Temporary dot files are now named `objgraph-*.dot` instead of `tmp*.dot`.
-        
-        - Python 3.3 support: no code changes, but some tests started failing because
-          the new and improved dictionary implementation no longer holds references to
-          str objects used as dict keys.
-        
-        - Added a tox.ini for convenient multi-Python testing.
-        
-        
-        1.7.1 (2011-12-11)
-        ------------------
-        
-        - Bugfix: non-ASCII characters in object representations would break graph
-          generation on Python 3.x, in some locales (e.g. with LC_ALL=C).  Reported and
-          fixed by `Stefano Rivera <https://launchpad.net/~stefanor>`_.
-        
-        - Bugfix: setup.py was broken on Python 3.x
-        
-        - Bugfix: dot.exe/xdot.exe were not found on Windows (`LP#767239
-          <https://launchpad.net/bugs/767239>`_).
-        
-        - Documentation updates: document the forgotten `find_ref_chain`,
-          update `show_chain` prototype.
-        
-        
-        1.7.0 (2011-03-11)
-        ------------------
-        
-        - New function: `find_ref_chain`.
-        
-        - New ``backrefs`` argument for `show_chain`.
-        
-        - New function: `get_leaking_objects`, based on `a blog post by
-          Kristján Valur
-          <https://cosmicpercolator.com/2010/12/08/finding-c-reference-leaks-using-the-gc-module/>`_.
-        
-        - New ``objects`` argument for `count`, `typestats`,
-          `most_common_types`, `show_most_common_types`, and
-          `by_type`.
-        
-        - Edges pointing to function attributes such as __defaults__ or __globals__
-          are now labeled.
-        
-        - Edge labels that are not simple strings now show the type.
-        
-        - Bugfix: '\0' and other unsafe characters used in a dictionary key could
-          break graph generation.
-        
-        - Bugfix: show_refs(..., filename='graph.dot') would then go to complain
-          about unrecognized file types and then produce a png.
-        
-        
-        1.6.0 (2010-12-18)
-        ------------------
-        
-        - Python 3 support, thanks to Stefano Rivera (fixes `LP#687601
-          <https://launchpad.net/bugs/687601>`_).
-        
-        - Removed weird weakref special-casing.
-        
-        
-        1.5.1 (2010-12-09)
-        ------------------
-        
-        - Avoid test failures in uncollectable-garbage.txt (fixes `LP#686731
-          <https://launchpad.net/bugs/686731>`_).
-        
-        - Added HACKING.txt (later renamed to HACKING.rst).
-        
-        
-        1.5.0 (2010-12-05)
-        ------------------
-        
-        - Show frame objects as well (fixes `LP#361704
-          <https://launchpad.net/bugs/361704>`_).
-        
-        - New functions: `show_growth`, `show_chain`.
-        
-        - `find_backref_chain` returns ``[obj]`` instead of ``None`` when a chain
-          could not be found.  This makes ``show_chain(find_backref_chain(...), ...)``
-          not break.
-        
-        - Show how many references were skipped from the output of
-          `show_refs`/`show_backrefs` by specifying ``too_many``.
-        
-        - Make `show_refs` descend into modules.
-        
-        - Do not highlight classes that define a ``__del__``, highlight only instances of
-          those classes.
-        
-        - Option to show reference counts in `show_refs`/`show_backrefs`.
-        
-        - Add `Sphinx <https://pypi.python.org/pypi/Sphinx>`_ documentation and a PyPI
-          long description.
-        
-        
-        1.4.0 (2010-11-03)
-        ------------------
-        
-        - Compatibility with Python 2.4 and 2.5 (``tempfile.NamedTemporaryFile`` has no
-          ``delete`` argument).
-        
-        - New function: `most_common_types`.
-        
-        
-        1.3.1 (2010-07-17)
-        ------------------
-        
-        - Rebuild an sdist with no missing files (fixes `LP#606604
-          <https://launchpad.net/bugs/606604>`_).
-        
-        - Added MANIFEST.in and a Makefile to check that setup.py sdist generates
-          source distributions with no files missing.
-        
-        
-        1.3 (2010-07-13)
-        ----------------
-        
-        - Highlight objects with a ``__del__`` method.
-        
-        - Fixes `LP#483411 <https://launchpad.net/bugs/483411>`_: suggest always passing
-          ``[obj]`` to `show_refs`, `show_backrefs`, since obj might be a
-          list/tuple.
-        
-        - Fixes `LP#514422 <https://launchpad.net/bugs/514422>`_: `show_refs`,
-          `show_backrefs` don't create files in the current working directory any
-          more.  Instead they accept a filename argument, which can be a .dot file or a
-          .png file.  If None or not specified, those functions will try to spawn xdot
-          as before.
-        
-        - New extra_info argument to graph-generating functions (patch by Thouis Jones,
-          `LP#558914 <https://launchpad.net/bugs/558914>`_).
-        
-        - setup.py should work with distutils now (`LP#604430
-          <https://launchpad.net/bugs/604430>`_, thanks to Randy Heydon).
-        
-        
-        1.2 (2009-03-25)
-        ----------------
-        
-        - Project website, public source repository, uploaded to PyPI.
-        
-        - No code changes.
-        
-        
-        1.1 (2008-09-10)
-        ----------------
-        
-        - New function: `show_refs` for showing forward references.
-        
-        - New functions: `typestats` and `show_most_common_types`.
-        
-        - Object boxes are less crammed with useless information (such as IDs).
-        
-        - Spawns `xdot <https://pypi.python.org/pypi/xdot>`_ if it is available.
-        
-        
-        1.0 (2008-06-14)
-        ----------------
-        
-        - First public release.
-        
+Project-URL: Source, https://github.com/mgedmin/objgraph
 Keywords: object graph visualization graphviz garbage collection
 Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
@@ -424,6 +14,431 @@ Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
-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: Programming Language :: Python :: 3.10
+Description-Content-Type: text/x-rst
+Provides-Extra: test
+License-File: LICENSE
+
+Python Object Graphs
+====================
+
+.. image:: https://github.com/mgedmin/objgraph/workflows/build/badge.svg?branch=master
+    :target: https://github.com/mgedmin/objgraph/actions
+   :alt: Build Status
+
+.. image:: https://ci.appveyor.com/api/projects/status/github/mgedmin/objgraph?branch=master&svg=true
+   :target: https://ci.appveyor.com/project/mgedmin/objgraph
+   :alt: Build Status (Windows)
+
+.. image:: https://coveralls.io/repos/mgedmin/objgraph/badge.svg?branch=master
+   :target: https://coveralls.io/r/mgedmin/objgraph?branch=master
+   :alt: Test Coverage
+
+.. image:: https://readthedocs.org/projects/objgraph/badge/?version=latest
+   :target: https://readthedocs.org/projects/objgraph/?badge=latest
+   :alt: Documentation Status
+
+
+``objgraph`` is a module that lets you visually explore Python object graphs.
+
+You'll need `graphviz <https://www.graphviz.org/>`_ if you want to draw
+the pretty graphs.
+
+I recommend `xdot <https://pypi.python.org/pypi/xdot>`_ for interactive use.
+``pip install xdot`` should suffice; objgraph will automatically look for it
+in your ``PATH``.
+
+
+Installation and Documentation
+------------------------------
+
+``pip install objgraph`` or `download it from PyPI
+<https://pypi.python.org/pypi/objgraph>`_.
+
+Documentation lives at https://mg.pov.lt/objgraph.
+
+
+.. _history:
+
+History
+-------
+
+I've developed a set of functions that eventually became objgraph when I
+was hunting for memory leaks in a Python program.  The whole story -- with
+illustrated examples -- is in this series of blog posts:
+
+* `Hunting memory leaks in Python
+  <https://mg.pov.lt/blog/hunting-python-memleaks.html>`_
+* `Python object graphs
+  <https://mg.pov.lt/blog/python-object-graphs.html>`_
+* `Object graphs with graphviz
+  <https://mg.pov.lt/blog/object-graphs-with-graphviz.html>`_
+
+
+.. _devel:
+
+Support and Development
+-----------------------
+
+The source code can be found in this Git repository:
+https://github.com/mgedmin/objgraph.
+
+To check it out, use ``git clone https://github.com/mgedmin/objgraph``.
+
+Report bugs at https://github.com/mgedmin/objgraph/issues.
+
+
+
+Changes
+=======
+
+
+
+3.5.1 (unreleased)
+------------------
+
+- Add support for Python 3.9 and 3.10.
+
+- Drop support for Python 3.6.
+
+
+3.5.0 (2020-10-11)
+------------------
+
+- Do not require ``mock`` for the test suite on Python 3; use unittest.mock
+  instead.
+
+- 100% test coverage for each version of Python rather than combined, using
+  ``coverage-python-version``.
+
+- Add the optional ``extra_node_attrs`` parameter to ``show_backrefs`` and
+  ``show_backrefs``
+
+- Fix IPython/Jupyter inline graph support code that would kick in even if you
+  explicitly passed a filename='foo.png' argument to
+  ``show_refs``/``show_backrefs``.  See `issue 47
+  <https://github.com/mgedmin/objgraph/issues/47>`_.
+
+- Add support for Python 3.8.
+
+- Drop support for Python 3.5.
+
+
+3.4.1 (2019-04-23)
+------------------
+
+- Add support for Python 3.7.
+
+- Drop support for Python 3.3 and 3.4.
+
+
+3.4.0 (2018-02-13)
+------------------
+
+- New functions: `get_new_ids`, `at_addrs`.
+
+  Contributed by Justin Black in `PR 36
+  <https://github.com/mgedmin/objgraph/pull/36>`_.
+
+
+3.3.0 (2017-12-28)
+------------------
+
+- New function: `growth`.
+
+
+3.2.0 (2017-12-20)
+------------------
+
+- New ``filter`` argument for `typestats`, `most_common_types`,
+  `show_most_common_types`, `show_growth`.
+
+- Show lambda functions in a more human-friendly way.
+
+
+3.1.2 (2017-11-27)
+------------------
+
+- Correct UTF-8 mojibake in the changelog and switch all links to HTTPS.
+
+
+3.1.1 (2017-10-30)
+------------------
+
+- Add support for Python 3.6.
+
+- Replace bare ``except:`` in ``safe_repr()`` with ``except Exception:``.
+
+
+3.1.0 (2016-12-07)
+------------------
+
+- Support displaying graphs inline in IPython/Jupyter notebooks (`issue 28
+  <https://github.com/mgedmin/objgraph/pull/28>`).
+
+
+3.0.1 (2016-09-17)
+------------------
+
+- The ``file`` argument of `show_most_common_types` and
+  `show_growth` now defaults to ``None`` instead of ``sys.stdout``.
+  ``None`` is interpreted to be the same as ``sys.stdout``, which means
+  the right stdout will be used if you change it at runtime (which happens,
+  in doctests).
+
+
+3.0.0 (2016-04-13)
+------------------
+
+- `show_most_common_types` and `show_growth` now accept a ``file``
+  argument if you want to redirect the output elsewhere.
+
+  Fixes `issue 24 <https://github.com/mgedmin/objgraph/pull/24>`_.  Contributed
+  by "d-sun-d".
+
+- Don't trust ``__class__`` to be accurate and ``__name__`` to be a string.
+  Fixes errors in some convoluted corner cases when mocks are involved.
+
+  Contributed by Andrew Shannon Brown in `PR 26
+  <https://github.com/mgedmin/objgraph/pull/26>`_.
+
+- Drop support for Python 2.4, 2.5, and 2.6.
+
+- Drop support for Python 3.1 and 3.2.
+
+- Add support for Python 3.5.
+
+
+2.0.1 (2015-07-28)
+------------------
+
+- Avoid creating reference cycles between the stack frame and the local
+  ``objects`` variable in `by_type`, `count`, and
+  `typestats`.
+
+  Fixes `issue 22 <https://github.com/mgedmin/objgraph/pull/22>`_.  Contributed
+  by Erik Bray.
+
+
+2.0.0 (2015-04-18)
+------------------
+
+- `show_refs` and `show_backrefs` now accept a file-like object
+  (via the new ``output`` argument) as an alternative to a filename.
+
+- Made internal helper methods private. This includes `find_chain`,
+  `show_graph`, `obj_node_id`, `obj_label`, `quote`,
+  `long_typename`, `safe_repr`, `short_repr`,
+  `gradient`, `edge_label`, and `_program_in_path`.
+
+- Correctly determine the name of old-style classes in `count`,
+  `by_type`, and graph drawing functions.
+
+  Fixes `issue 16 <https://github.com/mgedmin/objgraph/pull/16>`_.  Contributed
+  by Mike Lambert.
+
+
+1.8.1 (2014-05-15)
+------------------
+
+- Do not expect file objects to have an ``encoding`` attribute.  Makes objgraph
+  compatible with Eventlet's monkey-patching.
+
+  Fixes `issue 6 <https://github.com/mgedmin/objgraph/pull/6>`_.  Contributed
+  by Jakub Stasiak.
+
+
+1.8.0 (2014-02-13)
+------------------
+
+- Moved to GitHub.
+
+- Python 3.4 support (`LP#1270872 <https://launchpad.net/bugs/1270872>`_).
+
+- New function: `is_proper_module`.
+
+- New ``shortnames`` argument for `typestats`, `most_common_types`,
+  `show_most_common_types`, `show_growth`, `show_refs`,
+  and `show_backrefs`.
+
+  `count` and `by_type` accept fully-qualified type names now.
+
+  Fixes `issue 4 <https://github.com/mgedmin/objgraph/issues/4>`_.
+
+
+1.7.2 (2012-10-23)
+------------------
+
+- Bugfix: setup.py sdist was broken on Python 2.7 (UnicodeDecodeError in
+  tarfile).
+
+- The ``filename`` argument for `show_refs` and `show_backrefs` now
+  allows arbitrary image formats, not just PNG.  Patch by `Riccardo
+  Murri <https://launchpad.net/~rmurri>`_.
+
+- Temporary dot files are now named `objgraph-*.dot` instead of `tmp*.dot`.
+
+- Python 3.3 support: no code changes, but some tests started failing because
+  the new and improved dictionary implementation no longer holds references to
+  str objects used as dict keys.
+
+- Added a tox.ini for convenient multi-Python testing.
+
+
+1.7.1 (2011-12-11)
+------------------
+
+- Bugfix: non-ASCII characters in object representations would break graph
+  generation on Python 3.x, in some locales (e.g. with LC_ALL=C).  Reported and
+  fixed by `Stefano Rivera <https://launchpad.net/~stefanor>`_.
+
+- Bugfix: setup.py was broken on Python 3.x
+
+- Bugfix: dot.exe/xdot.exe were not found on Windows (`LP#767239
+  <https://launchpad.net/bugs/767239>`_).
+
+- Documentation updates: document the forgotten `find_ref_chain`,
+  update `show_chain` prototype.
+
+
+1.7.0 (2011-03-11)
+------------------
+
+- New function: `find_ref_chain`.
+
+- New ``backrefs`` argument for `show_chain`.
+
+- New function: `get_leaking_objects`, based on `a blog post by
+  Kristján Valur
+  <https://cosmicpercolator.com/2010/12/08/finding-c-reference-leaks-using-the-gc-module/>`_.
+
+- New ``objects`` argument for `count`, `typestats`,
+  `most_common_types`, `show_most_common_types`, and
+  `by_type`.
+
+- Edges pointing to function attributes such as __defaults__ or __globals__
+  are now labeled.
+
+- Edge labels that are not simple strings now show the type.
+
+- Bugfix: '\0' and other unsafe characters used in a dictionary key could
+  break graph generation.
+
+- Bugfix: show_refs(..., filename='graph.dot') would then go to complain
+  about unrecognized file types and then produce a png.
+
+
+1.6.0 (2010-12-18)
+------------------
+
+- Python 3 support, thanks to Stefano Rivera (fixes `LP#687601
+  <https://launchpad.net/bugs/687601>`_).
+
+- Removed weird weakref special-casing.
+
+
+1.5.1 (2010-12-09)
+------------------
+
+- Avoid test failures in uncollectable-garbage.txt (fixes `LP#686731
+  <https://launchpad.net/bugs/686731>`_).
+
+- Added HACKING.txt (later renamed to HACKING.rst).
+
+
+1.5.0 (2010-12-05)
+------------------
+
+- Show frame objects as well (fixes `LP#361704
+  <https://launchpad.net/bugs/361704>`_).
+
+- New functions: `show_growth`, `show_chain`.
+
+- `find_backref_chain` returns ``[obj]`` instead of ``None`` when a chain
+  could not be found.  This makes ``show_chain(find_backref_chain(...), ...)``
+  not break.
+
+- Show how many references were skipped from the output of
+  `show_refs`/`show_backrefs` by specifying ``too_many``.
+
+- Make `show_refs` descend into modules.
+
+- Do not highlight classes that define a ``__del__``, highlight only instances of
+  those classes.
+
+- Option to show reference counts in `show_refs`/`show_backrefs`.
+
+- Add `Sphinx <https://pypi.python.org/pypi/Sphinx>`_ documentation and a PyPI
+  long description.
+
+
+1.4.0 (2010-11-03)
+------------------
+
+- Compatibility with Python 2.4 and 2.5 (``tempfile.NamedTemporaryFile`` has no
+  ``delete`` argument).
+
+- New function: `most_common_types`.
+
+
+1.3.1 (2010-07-17)
+------------------
+
+- Rebuild an sdist with no missing files (fixes `LP#606604
+  <https://launchpad.net/bugs/606604>`_).
+
+- Added MANIFEST.in and a Makefile to check that setup.py sdist generates
+  source distributions with no files missing.
+
+
+1.3 (2010-07-13)
+----------------
+
+- Highlight objects with a ``__del__`` method.
+
+- Fixes `LP#483411 <https://launchpad.net/bugs/483411>`_: suggest always passing
+  ``[obj]`` to `show_refs`, `show_backrefs`, since obj might be a
+  list/tuple.
+
+- Fixes `LP#514422 <https://launchpad.net/bugs/514422>`_: `show_refs`,
+  `show_backrefs` don't create files in the current working directory any
+  more.  Instead they accept a filename argument, which can be a .dot file or a
+  .png file.  If None or not specified, those functions will try to spawn xdot
+  as before.
+
+- New extra_info argument to graph-generating functions (patch by Thouis Jones,
+  `LP#558914 <https://launchpad.net/bugs/558914>`_).
+
+- setup.py should work with distutils now (`LP#604430
+  <https://launchpad.net/bugs/604430>`_, thanks to Randy Heydon).
+
+
+1.2 (2009-03-25)
+----------------
+
+- Project website, public source repository, uploaded to PyPI.
+
+- No code changes.
+
+
+1.1 (2008-09-10)
+----------------
+
+- New function: `show_refs` for showing forward references.
+
+- New functions: `typestats` and `show_most_common_types`.
+
+- Object boxes are less crammed with useless information (such as IDs).
+
+- Spawns `xdot <https://pypi.python.org/pypi/xdot>`_ if it is available.
+
+
+1.0 (2008-06-14)
+----------------
+
+- First public release.
+
+
diff --git a/objgraph.egg-info/SOURCES.txt b/objgraph.egg-info/SOURCES.txt
index 9368fd0..0292b88 100644
--- a/objgraph.egg-info/SOURCES.txt
+++ b/objgraph.egg-info/SOURCES.txt
@@ -1,7 +1,6 @@
 .coveragerc
 .gitattributes
 .gitignore
-.travis.yml
 CHANGES.rst
 HACKING.rst
 LICENSE
diff --git a/objgraph.egg-info/requires.txt b/objgraph.egg-info/requires.txt
index 4d95609..f14d4aa 100644
--- a/objgraph.egg-info/requires.txt
+++ b/objgraph.egg-info/requires.txt
@@ -1 +1,6 @@
 graphviz
+
+[test]
+
+[test:python_version == "2.7"]
+mock
diff --git a/objgraph.py b/objgraph.py
index a1da76b..6c2c941 100755
--- a/objgraph.py
+++ b/objgraph.py
@@ -30,15 +30,15 @@ from __future__ import print_function
 import codecs
 import collections
 import gc
-import re
 import inspect
-import types
+import itertools
 import operator
 import os
+import re
 import subprocess
-import tempfile
 import sys
-import itertools
+import tempfile
+import types
 
 try:
     # Python 2.x compatibility
@@ -56,7 +56,7 @@ except ImportError:  # pragma: PY3
 __author__ = "Marius Gedminas (marius@gedmin.as)"
 __copyright__ = "Copyright (c) 2008-2017 Marius Gedminas and contributors"
 __license__ = "MIT"
-__version__ = '3.5.0'
+__version__ = '3.5.1.dev0'
 __date__ = '2020-10-11'
 
 
diff --git a/release.mk b/release.mk
index 539dff0..ff09689 100644
--- a/release.mk
+++ b/release.mk
@@ -1,4 +1,4 @@
-# release.mk version 2.0 (2020-10-11)
+# release.mk version 2.1 (2021-04-19)
 #
 # Helpful Makefile rules for releasing Python packages.
 # https://github.com/mgedmin/python-project-skel
@@ -142,18 +142,24 @@ release: releasechecklist do-release    ##: prepare a new PyPI release
 do-release:
 	$(release_recipe)
 
-ifndef release_recipe
-define release_recipe =
+define default_release_recipe_publish_and_tag =
 	# I'm chicken so I won't actually do these things yet
 	@echo "Please run"
 	@echo
 	@echo "  $(PYPI_PUBLISH)"
 	@echo "  $(VCS_TAG)"
 	@echo
+endef
+define default_release_recipe_increment_and_push =
 	@echo "Please increment the version number in $(FILE_WITH_VERSION)"
 	@echo "and add a new empty entry at the top of the changelog in $(FILE_WITH_CHANGELOG), then"
 	@echo
 	@echo '  $(VCS_COMMIT_AND_PUSH)'
 	@echo
 endef
+ifndef release_recipe
+define release_recipe =
+$(default_release_recipe_publish_and_tag)
+$(default_release_recipe_increment_and_push)
+endef
 endif
diff --git a/setup.py b/setup.py
index f28ca18..212bf73 100755
--- a/setup.py
+++ b/setup.py
@@ -64,24 +64,34 @@ setup(
     author='Marius Gedminas',
     author_email='marius@gedmin.as',
     url='https://mg.pov.lt/objgraph/',
+    project_urls={
+        'Source': 'https://github.com/mgedmin/objgraph',
+    },
     license='MIT',
     description='Draws Python object reference graphs with graphviz',
     long_description=get_description(),
+    long_description_content_type='text/x-rst',
     classifiers=[
         'Intended Audience :: Developers',
         'License :: OSI Approved :: MIT License',
         'Operating System :: OS Independent',
         'Programming Language :: Python',
         'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
+        'Programming Language :: Python :: 3.10',
     ],
     keywords='object graph visualization graphviz garbage collection',
     py_modules=['objgraph'],
     install_requires=[
         'graphviz',  # just for ipython support currently
     ],
+    extras_require={
+        'test': [
+            'mock;python_version=="2.7"',
+        ],
+    },
     tests_require=['mock;python_version=="2.7"'],
     test_suite='tests.test_suite',
     zip_safe=True,
diff --git a/tox.ini b/tox.ini
index 44db070..55f6d65 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27, py36, py37, py38
+envlist = py27, py37, py38, py39, py310
 
 [testenv]
 deps =
@@ -30,3 +30,23 @@ commands = {[testenv:coverage]commands}
 basepython = python3
 deps = {[testenv:coverage]deps}
 commands = {[testenv:coverage]commands}
+
+[testenv:flake8]
+deps = flake8
+skip_install = true
+commands = flake8 objgraph.py setup.py tests.py
+
+[testenv:isort]
+deps = isort
+skip_install = true
+commands = isort {posargs: -c --diff objgraph.py setup.py tests.py}
+
+[testenv:check-manifest]
+deps = check-manifest
+skip_install = true
+commands = check-manifest {posargs}
+
+[testenv:check-python-versions]
+deps = check-python-versions
+skip_install = true
+commands = check-python-versions {posargs}