Remove funcsigs, which is no longer used. am: c93c87abc9

Original change: https://android-review.googlesource.com/c/platform/external/python/funcsigs/+/2185742

Change-Id: Ia59e62b9f6d9e620cd38d46ea7dc67835a6aec76
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 2f4dfa8..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2018 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.
-
-package {
-    default_applicable_licenses: ["external_python_funcsigs_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
-    name: "external_python_funcsigs_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-Apache-2.0",
-        "SPDX-license-identifier-PSF-2.0",
-    ],
-    license_text: [
-        "LICENSE",
-    ],
-}
-
-python_test {
-  name: "py3-funcsigs-tests",
-  main: "Android_tests.py",
-  srcs: [
-      "tests/*.py",
-      "Android_tests.py",
-  ],
-  host_supported: true,
-  libs: ["py-funcsigs"],
-  data: ["README.rst"],
-}
diff --git a/Android_tests.py b/Android_tests.py
deleted file mode 100644
index ac84729..0000000
--- a/Android_tests.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2018 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.
-
-import os
-import sys
-import unittest
-
-# this runs any test*.py files located anywhere in this subtree
-if __name__ == '__main__':
-  test_loader = unittest.defaultTestLoader
-  # output is normal text formatting (as if running from a CLI), prints to stderr
-  test_runner = unittest.TextTestRunner(stream=sys.stderr)
-
-  # look at tests relative to the dir of this file.
-  this_dir = os.path.dirname(os.path.abspath(__file__))
-
-  # automagically find all tests recursively whose file name matches test*.py
-  test_suite = test_loader.discover(this_dir, pattern='test*.py')
-
-  # execute all the found tests
-  test_runner.run(test_suite)
-
diff --git a/CHANGELOG b/CHANGELOG
deleted file mode 100644
index 602eec5..0000000
--- a/CHANGELOG
+++ /dev/null
@@ -1,19 +0,0 @@
-Changelog
----------
-
-0.4 (2013-12-20)
-````````````````
-* Fix unbound methods getting their first parameter curried
-* Publish Python wheel packages
-
-0.3 (2013-05-29)
-````````````````
-* Fix annotation formatting of builtin types on Python 2.x
-
-0.2 (2012-01-07)
-````````````````
-* PyPy compatability
-
-0.1 (2012-01-06)
-````````````````
-* Initial release
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 3e563d6..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2013 Aaron Iles
-
-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.
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index f0abb42..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,7 +0,0 @@
-recursive-include docs *
-recursive-include tests *.py
-include *.py
-include CHANGELOG
-include LICENSE
-include MANIFEST.in
-include README.rst
diff --git a/METADATA b/METADATA
deleted file mode 100644
index 1539e3a..0000000
--- a/METADATA
+++ /dev/null
@@ -1,21 +0,0 @@
-name: "funcsigs"
-description:
-    "funcsigs is a backport of the PEP 362 function signature features from "
-    "Python 3.3's inspect module. The backport is compatible with Python 2.6, "
-    "2.7 as well as 3.2 and up. "
-    " "
-    "(The primary purpose for importing this is as a pytest dependency)"
-
-third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://pypi.org/project/funcsigs/"
-  }
-  url {
-    type: GIT
-    value: "https://github.com/aliles/funcsigs.git"
-  }
-  version: "0.4"
-  last_upgrade_date { year: 2018 month: 8 day: 2 }
-  license_type: NOTICE
-}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/Makefile b/Makefile
deleted file mode 100644
index e232923..0000000
--- a/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-SHELL := /bin/bash
-
-deps:
-	pip install --upgrade \
-	            -r requirements/development.txt \
-	            -r requirements/production.txt
-
-sdist:
-	python setup.py sdist
-	python setup.py bdist_wheel
-
-register:
-	python setup.py register
-	python setup.py sdist upload
-	python setup.py bdist_wheel upload
-
-site:
-	cd docs; make html
-
-test:
-	coverage run setup.py test
-
-unittest:
-	coverage run -m unittest discover
-
-lint:
-	flake8 --exit-zero funcsigs tests
-
-coverage:
-	coverage report --show-missing
-
-clean:
-	python setup.py clean --all
-	find . -type f -name "*.pyc" -exec rm '{}' +
-	find . -type d -name "__pycache__" -exec rmdir '{}' +
-	rm -rf *.egg-info .coverage
-	cd docs; make clean
-
-docs: site
diff --git a/OWNERS b/OWNERS
index 136a553..7529cb9 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1 @@
-# Default owners are top 3 or more active developers of the past 1 or 2 years
-# or people with more than 10 commits last year.
-# Please update this list if you find better owner candidates.
-iam@google.com
+include platform/system/core:/janitors/OWNERS
diff --git a/README.rst b/README.rst
deleted file mode 100644
index f04b7b4..0000000
--- a/README.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-funcsigs
-========
-
-``funcsigs`` is a backport of the `PEP 362`_ function signature features from
-Python 3.3's `inspect`_ module. The backport is compatible with Python 2.6, 2.7
-as well as 3.2 and up.
-
-|pypi_version|
-
-Documentation
--------------
-
-The reference documentation is standard library documentation for the
-`inspect`_ module in Python3. This documentation has been included in the
-``funcsigs`` package documentation hosted on `Read The Docs`_.
-
-Example
--------
-
-To obtain a signature object, pass the target function to the
-``funcsigs.signature`` function. ::
-
-    >>> from funcsigs import signature
-    >>> def foo(a, b=None, *args, **kwargs):
-    ...     pass
-
-    >>> sig = signature(foo)
-
-For the details of the signature object, refer to the either the package of
-standard library documentation.
-
-Compatability
--------------
-
-The ``funcsigs`` backport has been tested against:
-
-* CPython 2.6
-* CPython 2.7
-* CPython 3.2
-* PyPy 1.9
-
-Continuous integration testing is provided by `Travis CI`_.
-
-Under Python 2.x there is a compatability issue when a function is assigned to
-the ``__wrapped__`` property of a class after it has been constructed.
-Similiarily there under PyPy directly passing the ``__call__`` method of a
-builtin is also a compatability issues.  Otherwise the functionality is
-believed to be uniform between both Python2 and Python3.
-
-Issues
-------
-
-Source code for ``funcsigs`` is hosted on `GitHub`_. Any bug reports or feature
-requests can be made using GitHub's `issues system`_. |build_status| |coverage|
-
-Copyright
----------
-
-This is a derived work of CPython under the terms of the `PSF License
-Agreement`_. The original CPython inspect module, its unit tests and
-documentation are the copyright of the Python Software Foundation. The derived
-work is distributed under the `Apache License Version 2.0`_.
-
-.. _Apache License Version 2.0: http://opensource.org/licenses/Apache-2.0
-.. _GitHub: https://github.com/aliles/funcsigs
-.. _PSF License Agreement: http://docs.python.org/3/license.html#terms-and-conditions-for-accessing-or-otherwise-using-python
-.. _Travis CI: http://travis-ci.org/
-.. _Read The Docs: http://funcsigs.readthedocs.org/
-.. _PEP 362: http://www.python.org/dev/peps/pep-0362/
-.. _inspect: http://docs.python.org/3/library/inspect.html#introspecting-callables-with-the-signature-object
-.. _issues system: https://github.com/alies/funcsigs/issues
-
-.. |build_status| image:: https://secure.travis-ci.org/aliles/funcsigs.png?branch=master
-   :target: http://travis-ci.org/#!/aliles/funcsigs
-   :alt: Current build status
-
-.. |coverage| image:: https://coveralls.io/repos/aliles/funcsigs/badge.png?branch=master
-   :target: https://coveralls.io/r/aliles/funcsigs?branch=master
-   :alt: Coverage status
-
-.. |pypi_version| image:: https://pypip.in/v/funcsigs/badge.png
-   :target: https://crate.io/packages/funcsigs/
-   :alt: Latest PyPI version
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index f7ab3d1..0000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,153 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS    =
-SPHINXBUILD   = sphinx-build
-PAPER         =
-BUILDDIR      = _build
-
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
-	@echo "Please use \`make <target>' where <target> is one of"
-	@echo "  html       to make standalone HTML files"
-	@echo "  dirhtml    to make HTML files named index.html in directories"
-	@echo "  singlehtml to make a single large HTML file"
-	@echo "  pickle     to make pickle files"
-	@echo "  json       to make JSON files"
-	@echo "  htmlhelp   to make HTML files and a HTML help project"
-	@echo "  qthelp     to make HTML files and a qthelp project"
-	@echo "  devhelp    to make HTML files and a Devhelp project"
-	@echo "  epub       to make an epub"
-	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
-	@echo "  text       to make text files"
-	@echo "  man        to make manual pages"
-	@echo "  texinfo    to make Texinfo files"
-	@echo "  info       to make Texinfo files and run them through makeinfo"
-	@echo "  gettext    to make PO message catalogs"
-	@echo "  changes    to make an overview of all changed/added/deprecated items"
-	@echo "  linkcheck  to check all external links for integrity"
-	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
-
-clean:
-	-rm -rf $(BUILDDIR)
-
-html:
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
-	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
-	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
-	@echo
-	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
-	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-	@echo
-	@echo "Build finished; now you can process the pickle files."
-
-json:
-	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-	@echo
-	@echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
-	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-	@echo
-	@echo "Build finished; now you can run HTML Help Workshop with the" \
-	      ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
-	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-	@echo
-	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
-	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/funcsigs.qhcp"
-	@echo "To view the help file:"
-	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/funcsigs.qhc"
-
-devhelp:
-	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
-	@echo
-	@echo "Build finished."
-	@echo "To view the help file:"
-	@echo "# mkdir -p $$HOME/.local/share/devhelp/funcsigs"
-	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/funcsigs"
-	@echo "# devhelp"
-
-epub:
-	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
-	@echo
-	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo
-	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-	@echo "Run \`make' in that directory to run these through (pdf)latex" \
-	      "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo "Running LaTeX files through pdflatex..."
-	$(MAKE) -C $(BUILDDIR)/latex all-pdf
-	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
-	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
-	@echo
-	@echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
-	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
-	@echo
-	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
-	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-	@echo
-	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
-	@echo "Run \`make' in that directory to run these through makeinfo" \
-	      "(use \`make info' here to do that automatically)."
-
-info:
-	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-	@echo "Running Texinfo files through makeinfo..."
-	make -C $(BUILDDIR)/texinfo info
-	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
-	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
-	@echo
-	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
-	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-	@echo
-	@echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
-	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-	@echo
-	@echo "Link check complete; look for any errors in the above output " \
-	      "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
-	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-	@echo "Testing of doctests in the sources finished, look at the " \
-	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/docs/_templates/page.html b/docs/_templates/page.html
deleted file mode 100644
index 5e1e00b..0000000
--- a/docs/_templates/page.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends "!page.html" %}
-{% block extrahead %}
-    <a href="https://github.com/aliles/funcsigs">
-        <img style="position: absolute; top: 0; right: 0; border: 0;"
-             src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png"
-             alt="Fork me on GitHub">
-    </a>
-    {{ super() }}
-{% endblock %}
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index c6e4194..0000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,251 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# funcsigs documentation build configuration file, created by
-# sphinx-quickstart on Fri Apr 20 20:27:52 2012.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-# 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.insert(0, os.path.abspath('..'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = 'funcsigs'
-copyright = '2013, Aaron Iles'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-from funcsigs import __version__
-version = '.'.join(__version__.split('.')[:2])
-# The full version, including alpha/beta/rc tags.
-release = __version__
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  See the documentation for
-# a list of builtin themes.
-html_theme = 'agogo'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = []
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'funcsigsdoc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'funcsigs.tex', 'funcsigs Documentation',
-   'Aaron Iles', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
-    ('index', 'funcsigs', 'funcsigs Documentation',
-     ['Aaron Iles'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output ------------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-#  dir menu entry, description, category)
-texinfo_documents = [
-  ('index', 'funcsigs', 'funcsigs Documentation',
-   'Aaron Iles', 'funcsigs', 'One line description of project.',
-   'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {
-        'python3': ('http://docs.python.org/py3k', None),
-        'python': ('http://docs.python.org/', None)
-}
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index 5d0f42f..0000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,315 +0,0 @@
-.. funcsigs documentation master file, created by
-   sphinx-quickstart on Fri Apr 20 20:27:52 2012.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Introducing funcsigs
-====================
-
-The Funcsigs Package
---------------------
-
-*funcsigs* is a backport of the `PEP 362`_ function signature features from
-Python 3.3's `inspect`_ module. The backport is compatible with Python 2.6, 2.7
-as well as 3.2 and up.
-
-.. _PEP 362: http://www.python.org/dev/peps/pep-0362/
-.. _inspect: http://docs.python.org/3/library/inspect.html#introspecting-callables-with-the-signature-object
-
-Compatability
-`````````````
-
-The *funcsigs* backport has been tested against:
-
-* CPython 2.6
-* CPython 2.7
-* CPython 3.2
-* PyPy 1.9
-
-Continuous integration testing is provided by `Travis CI`_.
-
-Under Python 2.x there is a compatability issue when a function is assigned to
-the ``__wrapped__`` property of a class after it has been constructed.
-Similiarily there under PyPy directly passing the ``__call__`` method of a
-builtin is also a compatability issues.  Otherwise the functionality is
-believed to be uniform between both Python2 and Python3.
-
-.. _Travis CI: http://travis-ci.org/
-
-Issues
-``````
-
-Source code for *funcsigs* is hosted on `GitHub`_. Any bug reports or feature
-requests can be made using GitHub's `issues system`_.
-
-.. _GitHub: https://github.com/aliles/funcsigs
-.. _issues system: https://github.com/alies/funcsigs/issues
-
-Introspecting callables with the Signature object
--------------------------------------------------
-
-.. note::
-
-   This section of documentation is a direct repoduction of the Python
-   standard library documentation for the inspect module.
-
-The Signature object represents the call signature of a callable object and its
-return annotation.  To retrieve a Signature object, use the :func:`signature`
-function.
-
-.. function:: signature(callable)
-
-   Return a :class:`Signature` object for the given ``callable``::
-
-      >>> from inspect import signature
-      >>> def foo(a, *, b:int, **kwargs):
-      ...     pass
-
-      >>> sig = signature(foo)
-
-      >>> str(sig)
-      '(a, *, b:int, **kwargs)'
-
-      >>> str(sig.parameters['b'])
-      'b:int'
-
-      >>> sig.parameters['b'].annotation
-      <class 'int'>
-
-   Accepts a wide range of python callables, from plain functions and classes to
-   :func:`functools.partial` objects.
-
-   .. note::
-
-      Some callables may not be introspectable in certain implementations of
-      Python.  For example, in CPython, built-in functions defined in C provide
-      no metadata about their arguments.
-
-
-.. class:: Signature
-
-   A Signature object represents the call signature of a function and its return
-   annotation.  For each parameter accepted by the function it stores a
-   :class:`Parameter` object in its :attr:`parameters` collection.
-
-   Signature objects are *immutable*.  Use :meth:`Signature.replace` to make a
-   modified copy.
-
-   .. attribute:: Signature.empty
-
-      A special class-level marker to specify absence of a return annotation.
-
-   .. attribute:: Signature.parameters
-
-      An ordered mapping of parameters' names to the corresponding
-      :class:`Parameter` objects.
-
-   .. attribute:: Signature.return_annotation
-
-      The "return" annotation for the callable.  If the callable has no "return"
-      annotation, this attribute is set to :attr:`Signature.empty`.
-
-   .. method:: Signature.bind(*args, **kwargs)
-
-      Create a mapping from positional and keyword arguments to parameters.
-      Returns :class:`BoundArguments` if ``*args`` and ``**kwargs`` match the
-      signature, or raises a :exc:`TypeError`.
-
-   .. method:: Signature.bind_partial(*args, **kwargs)
-
-      Works the same way as :meth:`Signature.bind`, but allows the omission of
-      some required arguments (mimics :func:`functools.partial` behavior.)
-      Returns :class:`BoundArguments`, or raises a :exc:`TypeError` if the
-      passed arguments do not match the signature.
-
-   .. method:: Signature.replace(*[, parameters][, return_annotation])
-
-      Create a new Signature instance based on the instance replace was invoked
-      on.  It is possible to pass different ``parameters`` and/or
-      ``return_annotation`` to override the corresponding properties of the base
-      signature.  To remove return_annotation from the copied Signature, pass in
-      :attr:`Signature.empty`.
-
-      ::
-
-         >>> def test(a, b):
-         ...     pass
-         >>> sig = signature(test)
-         >>> new_sig = sig.replace(return_annotation="new return anno")
-         >>> str(new_sig)
-         "(a, b) -> 'new return anno'"
-
-
-.. class:: Parameter
-
-   Parameter objects are *immutable*.  Instead of modifying a Parameter object,
-   you can use :meth:`Parameter.replace` to create a modified copy.
-
-   .. attribute:: Parameter.empty
-
-      A special class-level marker to specify absence of default values and
-      annotations.
-
-   .. attribute:: Parameter.name
-
-      The name of the parameter as a string.  Must be a valid python identifier
-      name (with the exception of ``POSITIONAL_ONLY`` parameters, which can have
-      it set to ``None``).
-
-   .. attribute:: Parameter.default
-
-      The default value for the parameter.  If the parameter has no default
-      value, this attribute is set to :attr:`Parameter.empty`.
-
-   .. attribute:: Parameter.annotation
-
-      The annotation for the parameter.  If the parameter has no annotation,
-      this attribute is set to :attr:`Parameter.empty`.
-
-   .. attribute:: Parameter.kind
-
-      Describes how argument values are bound to the parameter.  Possible values
-      (accessible via :class:`Parameter`, like ``Parameter.KEYWORD_ONLY``):
-
-      +------------------------+----------------------------------------------+
-      |    Name                | Meaning                                      |
-      +========================+==============================================+
-      | *POSITIONAL_ONLY*      | Value must be supplied as a positional       |
-      |                        | argument.                                    |
-      |                        |                                              |
-      |                        | Python has no explicit syntax for defining   |
-      |                        | positional-only parameters, but many built-in|
-      |                        | and extension module functions (especially   |
-      |                        | those that accept only one or two parameters)|
-      |                        | accept them.                                 |
-      +------------------------+----------------------------------------------+
-      | *POSITIONAL_OR_KEYWORD*| Value may be supplied as either a keyword or |
-      |                        | positional argument (this is the standard    |
-      |                        | binding behaviour for functions implemented  |
-      |                        | in Python.)                                  |
-      +------------------------+----------------------------------------------+
-      | *VAR_POSITIONAL*       | A tuple of positional arguments that aren't  |
-      |                        | bound to any other parameter. This           |
-      |                        | corresponds to a ``*args`` parameter in a    |
-      |                        | Python function definition.                  |
-      +------------------------+----------------------------------------------+
-      | *KEYWORD_ONLY*         | Value must be supplied as a keyword argument.|
-      |                        | Keyword only parameters are those which      |
-      |                        | appear after a ``*`` or ``*args`` entry in a |
-      |                        | Python function definition.                  |
-      +------------------------+----------------------------------------------+
-      | *VAR_KEYWORD*          | A dict of keyword arguments that aren't bound|
-      |                        | to any other parameter. This corresponds to a|
-      |                        | ``**kwargs`` parameter in a Python function  |
-      |                        | definition.                                  |
-      +------------------------+----------------------------------------------+
-
-      Example: print all keyword-only arguments without default values::
-
-         >>> def foo(a, b, *, c, d=10):
-         ...     pass
-
-         >>> sig = signature(foo)
-         >>> for param in sig.parameters.values():
-         ...     if (param.kind == param.KEYWORD_ONLY and
-         ...                        param.default is param.empty):
-         ...         print('Parameter:', param)
-         Parameter: c
-
-   .. method:: Parameter.replace(*[, name][, kind][, default][, annotation])
-
-      Create a new Parameter instance based on the instance replaced was invoked
-      on.  To override a :class:`Parameter` attribute, pass the corresponding
-      argument.  To remove a default value or/and an annotation from a
-      Parameter, pass :attr:`Parameter.empty`.
-
-      ::
-
-         >>> from inspect import Parameter
-         >>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42)
-         >>> str(param)
-         'foo=42'
-
-         >>> str(param.replace()) # Will create a shallow copy of 'param'
-         'foo=42'
-
-         >>> str(param.replace(default=Parameter.empty, annotation='spam'))
-         "foo:'spam'"
-
-
-.. class:: BoundArguments
-
-   Result of a :meth:`Signature.bind` or :meth:`Signature.bind_partial` call.
-   Holds the mapping of arguments to the function's parameters.
-
-   .. attribute:: BoundArguments.arguments
-
-      An ordered, mutable mapping (:class:`collections.OrderedDict`) of
-      parameters' names to arguments' values.  Contains only explicitly bound
-      arguments.  Changes in :attr:`arguments` will reflect in :attr:`args` and
-      :attr:`kwargs`.
-
-      Should be used in conjunction with :attr:`Signature.parameters` for any
-      argument processing purposes.
-
-      .. note::
-
-         Arguments for which :meth:`Signature.bind` or
-         :meth:`Signature.bind_partial` relied on a default value are skipped.
-         However, if needed, it is easy to include them.
-
-      ::
-
-        >>> def foo(a, b=10):
-        ...     pass
-
-        >>> sig = signature(foo)
-        >>> ba = sig.bind(5)
-
-        >>> ba.args, ba.kwargs
-        ((5,), {})
-
-        >>> for param in sig.parameters.values():
-        ...     if param.name not in ba.arguments:
-        ...         ba.arguments[param.name] = param.default
-
-        >>> ba.args, ba.kwargs
-        ((5, 10), {})
-
-
-   .. attribute:: BoundArguments.args
-
-      A tuple of positional arguments values.  Dynamically computed from the
-      :attr:`arguments` attribute.
-
-   .. attribute:: BoundArguments.kwargs
-
-      A dict of keyword arguments values.  Dynamically computed from the
-      :attr:`arguments` attribute.
-
-   The :attr:`args` and :attr:`kwargs` properties can be used to invoke
-   functions::
-
-      def test(a, *, b):
-         ...
-
-      sig = signature(test)
-      ba = sig.bind(10, b=20)
-      test(*ba.args, **ba.kwargs)
-
-
-.. seealso::
-
-   :pep:`362` - Function Signature Object.
-      The detailed specification, implementation details and examples.
-
-Copyright
----------
-
-*funcsigs* is a derived work of CPython under the terms of the `PSF License
-Agreement`_. The original CPython inspect module, its unit tests and
-documentation are the copyright of the Python Software Foundation. The derived
-work is distributed under the `Apache License Version 2.0`_.
-
-.. _PSF License Agreement: http://docs.python.org/3/license.html#terms-and-conditions-for-accessing-or-otherwise-using-python
-.. _Apache License Version 2.0: http://opensource.org/licenses/Apache-2.0
diff --git a/funcsigs/Android.bp b/funcsigs/Android.bp
deleted file mode 100644
index 74882e7..0000000
--- a/funcsigs/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 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.
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "external_python_funcsigs_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["external_python_funcsigs_license"],
-}
-
-python_library {
-  name: "py-funcsigs",
-  host_supported: true,
-  srcs: [
-      "*.py",
-  ],
-  pkg_path: "funcsigs",
-}
diff --git a/funcsigs/__init__.py b/funcsigs/__init__.py
deleted file mode 100644
index fd2f47b..0000000
--- a/funcsigs/__init__.py
+++ /dev/null
@@ -1,818 +0,0 @@
-# Copyright 2001-2013 Python Software Foundation; All Rights Reserved
-"""Function signature objects for callables
-
-Back port of Python 3.3's function signature tools from the inspect module,
-modified to be compatible with Python 2.6, 2.7 and 3.2+.
-"""
-from __future__ import absolute_import, division, print_function
-import itertools
-import functools
-import re
-import types
-
-try:
-    from collections import OrderedDict
-except ImportError:
-    from funcsigs.odict import OrderedDict
-
-from funcsigs.version import __version__
-
-__all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
-
-
-_WrapperDescriptor = type(type.__call__)
-_MethodWrapper = type(all.__call__)
-
-_NonUserDefinedCallables = (_WrapperDescriptor,
-                            _MethodWrapper,
-                            types.BuiltinFunctionType)
-
-
-def formatannotation(annotation, base_module=None):
-    if isinstance(annotation, type):
-        if annotation.__module__ in ('builtins', '__builtin__', base_module):
-            return annotation.__name__
-        return annotation.__module__+'.'+annotation.__name__
-    return repr(annotation)
-
-
-def _get_user_defined_method(cls, method_name, *nested):
-    try:
-        if cls is type:
-            return
-        meth = getattr(cls, method_name)
-        for name in nested:
-            meth = getattr(meth, name, meth)
-    except AttributeError:
-        return
-    else:
-        if not isinstance(meth, _NonUserDefinedCallables):
-            # Once '__signature__' will be added to 'C'-level
-            # callables, this check won't be necessary
-            return meth
-
-
-def signature(obj):
-    '''Get a signature object for the passed callable.'''
-
-    if not callable(obj):
-        raise TypeError('{0!r} is not a callable object'.format(obj))
-
-    if isinstance(obj, types.MethodType):
-        sig = signature(obj.__func__)
-        if obj.__self__ is None:
-            # Unbound method: the first parameter becomes positional-only
-            if sig.parameters:
-                first = sig.parameters.values()[0].replace(
-                    kind=_POSITIONAL_ONLY)
-                return sig.replace(
-                    parameters=(first,) + tuple(sig.parameters.values())[1:])
-            else:
-                return sig
-        else:
-            # In this case we skip the first parameter of the underlying
-            # function (usually `self` or `cls`).
-            return sig.replace(parameters=tuple(sig.parameters.values())[1:])
-
-    try:
-        sig = obj.__signature__
-    except AttributeError:
-        pass
-    else:
-        if sig is not None:
-            return sig
-
-    try:
-        # Was this function wrapped by a decorator?
-        wrapped = obj.__wrapped__
-    except AttributeError:
-        pass
-    else:
-        return signature(wrapped)
-
-    if isinstance(obj, types.FunctionType):
-        return Signature.from_function(obj)
-
-    if isinstance(obj, functools.partial):
-        sig = signature(obj.func)
-
-        new_params = OrderedDict(sig.parameters.items())
-
-        partial_args = obj.args or ()
-        partial_keywords = obj.keywords or {}
-        try:
-            ba = sig.bind_partial(*partial_args, **partial_keywords)
-        except TypeError as ex:
-            msg = 'partial object {0!r} has incorrect arguments'.format(obj)
-            raise ValueError(msg)
-
-        for arg_name, arg_value in ba.arguments.items():
-            param = new_params[arg_name]
-            if arg_name in partial_keywords:
-                # We set a new default value, because the following code
-                # is correct:
-                #
-                #   >>> def foo(a): print(a)
-                #   >>> print(partial(partial(foo, a=10), a=20)())
-                #   20
-                #   >>> print(partial(partial(foo, a=10), a=20)(a=30))
-                #   30
-                #
-                # So, with 'partial' objects, passing a keyword argument is
-                # like setting a new default value for the corresponding
-                # parameter
-                #
-                # We also mark this parameter with '_partial_kwarg'
-                # flag.  Later, in '_bind', the 'default' value of this
-                # parameter will be added to 'kwargs', to simulate
-                # the 'functools.partial' real call.
-                new_params[arg_name] = param.replace(default=arg_value,
-                                                     _partial_kwarg=True)
-
-            elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
-                            not param._partial_kwarg):
-                new_params.pop(arg_name)
-
-        return sig.replace(parameters=new_params.values())
-
-    sig = None
-    if isinstance(obj, type):
-        # obj is a class or a metaclass
-
-        # First, let's see if it has an overloaded __call__ defined
-        # in its metaclass
-        call = _get_user_defined_method(type(obj), '__call__')
-        if call is not None:
-            sig = signature(call)
-        else:
-            # Now we check if the 'obj' class has a '__new__' method
-            new = _get_user_defined_method(obj, '__new__')
-            if new is not None:
-                sig = signature(new)
-            else:
-                # Finally, we should have at least __init__ implemented
-                init = _get_user_defined_method(obj, '__init__')
-                if init is not None:
-                    sig = signature(init)
-    elif not isinstance(obj, _NonUserDefinedCallables):
-        # An object with __call__
-        # We also check that the 'obj' is not an instance of
-        # _WrapperDescriptor or _MethodWrapper to avoid
-        # infinite recursion (and even potential segfault)
-        call = _get_user_defined_method(type(obj), '__call__', 'im_func')
-        if call is not None:
-            sig = signature(call)
-
-    if sig is not None:
-        # For classes and objects we skip the first parameter of their
-        # __call__, __new__, or __init__ methods
-        return sig.replace(parameters=tuple(sig.parameters.values())[1:])
-
-    if isinstance(obj, types.BuiltinFunctionType):
-        # Raise a nicer error message for builtins
-        msg = 'no signature found for builtin function {0!r}'.format(obj)
-        raise ValueError(msg)
-
-    raise ValueError('callable {0!r} is not supported by signature'.format(obj))
-
-
-class _void(object):
-    '''A private marker - used in Parameter & Signature'''
-
-
-class _empty(object):
-    pass
-
-
-class _ParameterKind(int):
-    def __new__(self, *args, **kwargs):
-        obj = int.__new__(self, *args)
-        obj._name = kwargs['name']
-        return obj
-
-    def __str__(self):
-        return self._name
-
-    def __repr__(self):
-        return '<_ParameterKind: {0!r}>'.format(self._name)
-
-
-_POSITIONAL_ONLY        = _ParameterKind(0, name='POSITIONAL_ONLY')
-_POSITIONAL_OR_KEYWORD  = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
-_VAR_POSITIONAL         = _ParameterKind(2, name='VAR_POSITIONAL')
-_KEYWORD_ONLY           = _ParameterKind(3, name='KEYWORD_ONLY')
-_VAR_KEYWORD            = _ParameterKind(4, name='VAR_KEYWORD')
-
-
-class Parameter(object):
-    '''Represents a parameter in a function signature.
-
-    Has the following public attributes:
-
-    * name : str
-        The name of the parameter as a string.
-    * default : object
-        The default value for the parameter if specified.  If the
-        parameter has no default value, this attribute is not set.
-    * annotation
-        The annotation for the parameter if specified.  If the
-        parameter has no annotation, this attribute is not set.
-    * kind : str
-        Describes how argument values are bound to the parameter.
-        Possible values: `Parameter.POSITIONAL_ONLY`,
-        `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
-        `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
-    '''
-
-    __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
-
-    POSITIONAL_ONLY         = _POSITIONAL_ONLY
-    POSITIONAL_OR_KEYWORD   = _POSITIONAL_OR_KEYWORD
-    VAR_POSITIONAL          = _VAR_POSITIONAL
-    KEYWORD_ONLY            = _KEYWORD_ONLY
-    VAR_KEYWORD             = _VAR_KEYWORD
-
-    empty = _empty
-
-    def __init__(self, name, kind, default=_empty, annotation=_empty,
-                 _partial_kwarg=False):
-
-        if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
-                        _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
-            raise ValueError("invalid value for 'Parameter.kind' attribute")
-        self._kind = kind
-
-        if default is not _empty:
-            if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
-                msg = '{0} parameters cannot have default values'.format(kind)
-                raise ValueError(msg)
-        self._default = default
-        self._annotation = annotation
-
-        if name is None:
-            if kind != _POSITIONAL_ONLY:
-                raise ValueError("None is not a valid name for a "
-                                 "non-positional-only parameter")
-            self._name = name
-        else:
-            name = str(name)
-            if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I):
-                msg = '{0!r} is not a valid parameter name'.format(name)
-                raise ValueError(msg)
-            self._name = name
-
-        self._partial_kwarg = _partial_kwarg
-
-    @property
-    def name(self):
-        return self._name
-
-    @property
-    def default(self):
-        return self._default
-
-    @property
-    def annotation(self):
-        return self._annotation
-
-    @property
-    def kind(self):
-        return self._kind
-
-    def replace(self, name=_void, kind=_void, annotation=_void,
-                default=_void, _partial_kwarg=_void):
-        '''Creates a customized copy of the Parameter.'''
-
-        if name is _void:
-            name = self._name
-
-        if kind is _void:
-            kind = self._kind
-
-        if annotation is _void:
-            annotation = self._annotation
-
-        if default is _void:
-            default = self._default
-
-        if _partial_kwarg is _void:
-            _partial_kwarg = self._partial_kwarg
-
-        return type(self)(name, kind, default=default, annotation=annotation,
-                          _partial_kwarg=_partial_kwarg)
-
-    def __str__(self):
-        kind = self.kind
-
-        formatted = self._name
-        if kind == _POSITIONAL_ONLY:
-            if formatted is None:
-                formatted = ''
-            formatted = '<{0}>'.format(formatted)
-
-        # Add annotation and default value
-        if self._annotation is not _empty:
-            formatted = '{0}:{1}'.format(formatted,
-                                       formatannotation(self._annotation))
-
-        if self._default is not _empty:
-            formatted = '{0}={1}'.format(formatted, repr(self._default))
-
-        if kind == _VAR_POSITIONAL:
-            formatted = '*' + formatted
-        elif kind == _VAR_KEYWORD:
-            formatted = '**' + formatted
-
-        return formatted
-
-    def __repr__(self):
-        return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,
-                                           id(self), self.name)
-
-    def __hash__(self):
-        msg = "unhashable type: '{0}'".format(self.__class__.__name__)
-        raise TypeError(msg)
-
-    def __eq__(self, other):
-        return (issubclass(other.__class__, Parameter) and
-                self._name == other._name and
-                self._kind == other._kind and
-                self._default == other._default and
-                self._annotation == other._annotation)
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-
-class BoundArguments(object):
-    '''Result of `Signature.bind` call.  Holds the mapping of arguments
-    to the function's parameters.
-
-    Has the following public attributes:
-
-    * arguments : OrderedDict
-        An ordered mutable mapping of parameters' names to arguments' values.
-        Does not contain arguments' default values.
-    * signature : Signature
-        The Signature object that created this instance.
-    * args : tuple
-        Tuple of positional arguments values.
-    * kwargs : dict
-        Dict of keyword arguments values.
-    '''
-
-    def __init__(self, signature, arguments):
-        self.arguments = arguments
-        self._signature = signature
-
-    @property
-    def signature(self):
-        return self._signature
-
-    @property
-    def args(self):
-        args = []
-        for param_name, param in self._signature.parameters.items():
-            if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
-                                                    param._partial_kwarg):
-                # Keyword arguments mapped by 'functools.partial'
-                # (Parameter._partial_kwarg is True) are mapped
-                # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
-                # KEYWORD_ONLY
-                break
-
-            try:
-                arg = self.arguments[param_name]
-            except KeyError:
-                # We're done here. Other arguments
-                # will be mapped in 'BoundArguments.kwargs'
-                break
-            else:
-                if param.kind == _VAR_POSITIONAL:
-                    # *args
-                    args.extend(arg)
-                else:
-                    # plain argument
-                    args.append(arg)
-
-        return tuple(args)
-
-    @property
-    def kwargs(self):
-        kwargs = {}
-        kwargs_started = False
-        for param_name, param in self._signature.parameters.items():
-            if not kwargs_started:
-                if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
-                                                param._partial_kwarg):
-                    kwargs_started = True
-                else:
-                    if param_name not in self.arguments:
-                        kwargs_started = True
-                        continue
-
-            if not kwargs_started:
-                continue
-
-            try:
-                arg = self.arguments[param_name]
-            except KeyError:
-                pass
-            else:
-                if param.kind == _VAR_KEYWORD:
-                    # **kwargs
-                    kwargs.update(arg)
-                else:
-                    # plain keyword argument
-                    kwargs[param_name] = arg
-
-        return kwargs
-
-    def __hash__(self):
-        msg = "unhashable type: '{0}'".format(self.__class__.__name__)
-        raise TypeError(msg)
-
-    def __eq__(self, other):
-        return (issubclass(other.__class__, BoundArguments) and
-                self.signature == other.signature and
-                self.arguments == other.arguments)
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-
-class Signature(object):
-    '''A Signature object represents the overall signature of a function.
-    It stores a Parameter object for each parameter accepted by the
-    function, as well as information specific to the function itself.
-
-    A Signature object has the following public attributes and methods:
-
-    * parameters : OrderedDict
-        An ordered mapping of parameters' names to the corresponding
-        Parameter objects (keyword-only arguments are in the same order
-        as listed in `code.co_varnames`).
-    * return_annotation : object
-        The annotation for the return type of the function if specified.
-        If the function has no annotation for its return type, this
-        attribute is not set.
-    * bind(*args, **kwargs) -> BoundArguments
-        Creates a mapping from positional and keyword arguments to
-        parameters.
-    * bind_partial(*args, **kwargs) -> BoundArguments
-        Creates a partial mapping from positional and keyword arguments
-        to parameters (simulating 'functools.partial' behavior.)
-    '''
-
-    __slots__ = ('_return_annotation', '_parameters')
-
-    _parameter_cls = Parameter
-    _bound_arguments_cls = BoundArguments
-
-    empty = _empty
-
-    def __init__(self, parameters=None, return_annotation=_empty,
-                 __validate_parameters__=True):
-        '''Constructs Signature from the given list of Parameter
-        objects and 'return_annotation'.  All arguments are optional.
-        '''
-
-        if parameters is None:
-            params = OrderedDict()
-        else:
-            if __validate_parameters__:
-                params = OrderedDict()
-                top_kind = _POSITIONAL_ONLY
-
-                for idx, param in enumerate(parameters):
-                    kind = param.kind
-                    if kind < top_kind:
-                        msg = 'wrong parameter order: {0} before {1}'
-                        msg = msg.format(top_kind, param.kind)
-                        raise ValueError(msg)
-                    else:
-                        top_kind = kind
-
-                    name = param.name
-                    if name is None:
-                        name = str(idx)
-                        param = param.replace(name=name)
-
-                    if name in params:
-                        msg = 'duplicate parameter name: {0!r}'.format(name)
-                        raise ValueError(msg)
-                    params[name] = param
-            else:
-                params = OrderedDict(((param.name, param)
-                                                for param in parameters))
-
-        self._parameters = params
-        self._return_annotation = return_annotation
-
-    @classmethod
-    def from_function(cls, func):
-        '''Constructs Signature for the given python function'''
-
-        if not isinstance(func, types.FunctionType):
-            raise TypeError('{0!r} is not a Python function'.format(func))
-
-        Parameter = cls._parameter_cls
-
-        # Parameter information.
-        func_code = func.__code__
-        pos_count = func_code.co_argcount
-        arg_names = func_code.co_varnames
-        positional = tuple(arg_names[:pos_count])
-        keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
-        keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
-        annotations = getattr(func, '__annotations__', {})
-        defaults = func.__defaults__
-        kwdefaults = getattr(func, '__kwdefaults__', None)
-
-        if defaults:
-            pos_default_count = len(defaults)
-        else:
-            pos_default_count = 0
-
-        parameters = []
-
-        # Non-keyword-only parameters w/o defaults.
-        non_default_count = pos_count - pos_default_count
-        for name in positional[:non_default_count]:
-            annotation = annotations.get(name, _empty)
-            parameters.append(Parameter(name, annotation=annotation,
-                                        kind=_POSITIONAL_OR_KEYWORD))
-
-        # ... w/ defaults.
-        for offset, name in enumerate(positional[non_default_count:]):
-            annotation = annotations.get(name, _empty)
-            parameters.append(Parameter(name, annotation=annotation,
-                                        kind=_POSITIONAL_OR_KEYWORD,
-                                        default=defaults[offset]))
-
-        # *args
-        if func_code.co_flags & 0x04:
-            name = arg_names[pos_count + keyword_only_count]
-            annotation = annotations.get(name, _empty)
-            parameters.append(Parameter(name, annotation=annotation,
-                                        kind=_VAR_POSITIONAL))
-
-        # Keyword-only parameters.
-        for name in keyword_only:
-            default = _empty
-            if kwdefaults is not None:
-                default = kwdefaults.get(name, _empty)
-
-            annotation = annotations.get(name, _empty)
-            parameters.append(Parameter(name, annotation=annotation,
-                                        kind=_KEYWORD_ONLY,
-                                        default=default))
-        # **kwargs
-        if func_code.co_flags & 0x08:
-            index = pos_count + keyword_only_count
-            if func_code.co_flags & 0x04:
-                index += 1
-
-            name = arg_names[index]
-            annotation = annotations.get(name, _empty)
-            parameters.append(Parameter(name, annotation=annotation,
-                                        kind=_VAR_KEYWORD))
-
-        return cls(parameters,
-                   return_annotation=annotations.get('return', _empty),
-                   __validate_parameters__=False)
-
-    @property
-    def parameters(self):
-        try:
-            return types.MappingProxyType(self._parameters)
-        except AttributeError:
-            return OrderedDict(self._parameters.items())
-
-    @property
-    def return_annotation(self):
-        return self._return_annotation
-
-    def replace(self, parameters=_void, return_annotation=_void):
-        '''Creates a customized copy of the Signature.
-        Pass 'parameters' and/or 'return_annotation' arguments
-        to override them in the new copy.
-        '''
-
-        if parameters is _void:
-            parameters = self.parameters.values()
-
-        if return_annotation is _void:
-            return_annotation = self._return_annotation
-
-        return type(self)(parameters,
-                          return_annotation=return_annotation)
-
-    def __hash__(self):
-        msg = "unhashable type: '{0}'".format(self.__class__.__name__)
-        raise TypeError(msg)
-
-    def __eq__(self, other):
-        if (not issubclass(type(other), Signature) or
-                    self.return_annotation != other.return_annotation or
-                    len(self.parameters) != len(other.parameters)):
-            return False
-
-        other_positions = dict((param, idx)
-                           for idx, param in enumerate(other.parameters.keys()))
-
-        for idx, (param_name, param) in enumerate(self.parameters.items()):
-            if param.kind == _KEYWORD_ONLY:
-                try:
-                    other_param = other.parameters[param_name]
-                except KeyError:
-                    return False
-                else:
-                    if param != other_param:
-                        return False
-            else:
-                try:
-                    other_idx = other_positions[param_name]
-                except KeyError:
-                    return False
-                else:
-                    if (idx != other_idx or
-                                    param != other.parameters[param_name]):
-                        return False
-
-        return True
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def _bind(self, args, kwargs, partial=False):
-        '''Private method.  Don't use directly.'''
-
-        arguments = OrderedDict()
-
-        parameters = iter(self.parameters.values())
-        parameters_ex = ()
-        arg_vals = iter(args)
-
-        if partial:
-            # Support for binding arguments to 'functools.partial' objects.
-            # See 'functools.partial' case in 'signature()' implementation
-            # for details.
-            for param_name, param in self.parameters.items():
-                if (param._partial_kwarg and param_name not in kwargs):
-                    # Simulating 'functools.partial' behavior
-                    kwargs[param_name] = param.default
-
-        while True:
-            # Let's iterate through the positional arguments and corresponding
-            # parameters
-            try:
-                arg_val = next(arg_vals)
-            except StopIteration:
-                # No more positional arguments
-                try:
-                    param = next(parameters)
-                except StopIteration:
-                    # No more parameters. That's it. Just need to check that
-                    # we have no `kwargs` after this while loop
-                    break
-                else:
-                    if param.kind == _VAR_POSITIONAL:
-                        # That's OK, just empty *args.  Let's start parsing
-                        # kwargs
-                        break
-                    elif param.name in kwargs:
-                        if param.kind == _POSITIONAL_ONLY:
-                            msg = '{arg!r} parameter is positional only, ' \
-                                  'but was passed as a keyword'
-                            msg = msg.format(arg=param.name)
-                            raise TypeError(msg)
-                        parameters_ex = (param,)
-                        break
-                    elif (param.kind == _VAR_KEYWORD or
-                                                param.default is not _empty):
-                        # That's fine too - we have a default value for this
-                        # parameter.  So, lets start parsing `kwargs`, starting
-                        # with the current parameter
-                        parameters_ex = (param,)
-                        break
-                    else:
-                        if partial:
-                            parameters_ex = (param,)
-                            break
-                        else:
-                            msg = '{arg!r} parameter lacking default value'
-                            msg = msg.format(arg=param.name)
-                            raise TypeError(msg)
-            else:
-                # We have a positional argument to process
-                try:
-                    param = next(parameters)
-                except StopIteration:
-                    raise TypeError('too many positional arguments')
-                else:
-                    if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
-                        # Looks like we have no parameter for this positional
-                        # argument
-                        raise TypeError('too many positional arguments')
-
-                    if param.kind == _VAR_POSITIONAL:
-                        # We have an '*args'-like argument, let's fill it with
-                        # all positional arguments we have left and move on to
-                        # the next phase
-                        values = [arg_val]
-                        values.extend(arg_vals)
-                        arguments[param.name] = tuple(values)
-                        break
-
-                    if param.name in kwargs:
-                        raise TypeError('multiple values for argument '
-                                        '{arg!r}'.format(arg=param.name))
-
-                    arguments[param.name] = arg_val
-
-        # Now, we iterate through the remaining parameters to process
-        # keyword arguments
-        kwargs_param = None
-        for param in itertools.chain(parameters_ex, parameters):
-            if param.kind == _POSITIONAL_ONLY:
-                # This should never happen in case of a properly built
-                # Signature object (but let's have this check here
-                # to ensure correct behaviour just in case)
-                raise TypeError('{arg!r} parameter is positional only, '
-                                'but was passed as a keyword'. \
-                                format(arg=param.name))
-
-            if param.kind == _VAR_KEYWORD:
-                # Memorize that we have a '**kwargs'-like parameter
-                kwargs_param = param
-                continue
-
-            param_name = param.name
-            try:
-                arg_val = kwargs.pop(param_name)
-            except KeyError:
-                # We have no value for this parameter.  It's fine though,
-                # if it has a default value, or it is an '*args'-like
-                # parameter, left alone by the processing of positional
-                # arguments.
-                if (not partial and param.kind != _VAR_POSITIONAL and
-                                                    param.default is _empty):
-                    raise TypeError('{arg!r} parameter lacking default value'. \
-                                    format(arg=param_name))
-
-            else:
-                arguments[param_name] = arg_val
-
-        if kwargs:
-            if kwargs_param is not None:
-                # Process our '**kwargs'-like parameter
-                arguments[kwargs_param.name] = kwargs
-            else:
-                raise TypeError('too many keyword arguments')
-
-        return self._bound_arguments_cls(self, arguments)
-
-    def bind(self, *args, **kwargs):
-        '''Get a BoundArguments object, that maps the passed `args`
-        and `kwargs` to the function's signature.  Raises `TypeError`
-        if the passed arguments can not be bound.
-        '''
-        return self._bind(args, kwargs)
-
-    def bind_partial(self, *args, **kwargs):
-        '''Get a BoundArguments object, that partially maps the
-        passed `args` and `kwargs` to the function's signature.
-        Raises `TypeError` if the passed arguments can not be bound.
-        '''
-        return self._bind(args, kwargs, partial=True)
-
-    def __str__(self):
-        result = []
-        render_kw_only_separator = True
-        for idx, param in enumerate(self.parameters.values()):
-            formatted = str(param)
-
-            kind = param.kind
-            if kind == _VAR_POSITIONAL:
-                # OK, we have an '*args'-like parameter, so we won't need
-                # a '*' to separate keyword-only arguments
-                render_kw_only_separator = False
-            elif kind == _KEYWORD_ONLY and render_kw_only_separator:
-                # We have a keyword-only parameter to render and we haven't
-                # rendered an '*args'-like parameter before, so add a '*'
-                # separator to the parameters list ("foo(arg1, *, arg2)" case)
-                result.append('*')
-                # This condition should be only triggered once, so
-                # reset the flag
-                render_kw_only_separator = False
-
-            result.append(formatted)
-
-        rendered = '({0})'.format(', '.join(result))
-
-        if self.return_annotation is not _empty:
-            anno = formatannotation(self.return_annotation)
-            rendered += ' -> {0}'.format(anno)
-
-        return rendered
diff --git a/funcsigs/odict.py b/funcsigs/odict.py
deleted file mode 100644
index 6221e97..0000000
--- a/funcsigs/odict.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
-# Passes Python2.7's test suite and incorporates all the latest updates.
-# Copyright 2009 Raymond Hettinger
-# http://code.activestate.com/recipes/576693/
-"Ordered dictionary"
-
-try:
-    from thread import get_ident as _get_ident
-except ImportError:
-    from dummy_thread import get_ident as _get_ident
-
-try:
-    from _abcoll import KeysView, ValuesView, ItemsView
-except ImportError:
-    pass
-
-
-class OrderedDict(dict):
-    'Dictionary that remembers insertion order'
-    # An inherited dict maps keys to values.
-    # The inherited dict provides __getitem__, __len__, __contains__, and get.
-    # The remaining methods are order-aware.
-    # Big-O running times for all methods are the same as for regular dictionaries.
-
-    # The internal self.__map dictionary maps keys to links in a doubly linked list.
-    # The circular doubly linked list starts and ends with a sentinel element.
-    # The sentinel element never gets deleted (this simplifies the algorithm).
-    # Each link is stored as a list of length three:  [PREV, NEXT, KEY].
-
-    def __init__(self, *args, **kwds):
-        '''Initialize an ordered dictionary.  Signature is the same as for
-        regular dictionaries, but keyword arguments are not recommended
-        because their insertion order is arbitrary.
-
-        '''
-        if len(args) > 1:
-            raise TypeError('expected at most 1 arguments, got %d' % len(args))
-        try:
-            self.__root
-        except AttributeError:
-            self.__root = root = []                     # sentinel node
-            root[:] = [root, root, None]
-            self.__map = {}
-        self.__update(*args, **kwds)
-
-    def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
-        'od.__setitem__(i, y) <==> od[i]=y'
-        # Setting a new item creates a new link which goes at the end of the linked
-        # list, and the inherited dictionary is updated with the new key/value pair.
-        if key not in self:
-            root = self.__root
-            last = root[0]
-            last[1] = root[0] = self.__map[key] = [last, root, key]
-        dict_setitem(self, key, value)
-
-    def __delitem__(self, key, dict_delitem=dict.__delitem__):
-        'od.__delitem__(y) <==> del od[y]'
-        # Deleting an existing item uses self.__map to find the link which is
-        # then removed by updating the links in the predecessor and successor nodes.
-        dict_delitem(self, key)
-        link_prev, link_next, key = self.__map.pop(key)
-        link_prev[1] = link_next
-        link_next[0] = link_prev
-
-    def __iter__(self):
-        'od.__iter__() <==> iter(od)'
-        root = self.__root
-        curr = root[1]
-        while curr is not root:
-            yield curr[2]
-            curr = curr[1]
-
-    def __reversed__(self):
-        'od.__reversed__() <==> reversed(od)'
-        root = self.__root
-        curr = root[0]
-        while curr is not root:
-            yield curr[2]
-            curr = curr[0]
-
-    def clear(self):
-        'od.clear() -> None.  Remove all items from od.'
-        try:
-            for node in self.__map.itervalues():
-                del node[:]
-            root = self.__root
-            root[:] = [root, root, None]
-            self.__map.clear()
-        except AttributeError:
-            pass
-        dict.clear(self)
-
-    def popitem(self, last=True):
-        '''od.popitem() -> (k, v), return and remove a (key, value) pair.
-        Pairs are returned in LIFO order if last is true or FIFO order if false.
-
-        '''
-        if not self:
-            raise KeyError('dictionary is empty')
-        root = self.__root
-        if last:
-            link = root[0]
-            link_prev = link[0]
-            link_prev[1] = root
-            root[0] = link_prev
-        else:
-            link = root[1]
-            link_next = link[1]
-            root[1] = link_next
-            link_next[0] = root
-        key = link[2]
-        del self.__map[key]
-        value = dict.pop(self, key)
-        return key, value
-
-    # -- the following methods do not depend on the internal structure --
-
-    def keys(self):
-        'od.keys() -> list of keys in od'
-        return list(self)
-
-    def values(self):
-        'od.values() -> list of values in od'
-        return [self[key] for key in self]
-
-    def items(self):
-        'od.items() -> list of (key, value) pairs in od'
-        return [(key, self[key]) for key in self]
-
-    def iterkeys(self):
-        'od.iterkeys() -> an iterator over the keys in od'
-        return iter(self)
-
-    def itervalues(self):
-        'od.itervalues -> an iterator over the values in od'
-        for k in self:
-            yield self[k]
-
-    def iteritems(self):
-        'od.iteritems -> an iterator over the (key, value) items in od'
-        for k in self:
-            yield (k, self[k])
-
-    def update(*args, **kwds):
-        '''od.update(E, **F) -> None.  Update od from dict/iterable E and F.
-
-        If E is a dict instance, does:           for k in E: od[k] = E[k]
-        If E has a .keys() method, does:         for k in E.keys(): od[k] = E[k]
-        Or if E is an iterable of items, does:   for k, v in E: od[k] = v
-        In either case, this is followed by:     for k, v in F.items(): od[k] = v
-
-        '''
-        if len(args) > 2:
-            raise TypeError('update() takes at most 2 positional '
-                            'arguments (%d given)' % (len(args),))
-        elif not args:
-            raise TypeError('update() takes at least 1 argument (0 given)')
-        self = args[0]
-        # Make progressively weaker assumptions about "other"
-        other = ()
-        if len(args) == 2:
-            other = args[1]
-        if isinstance(other, dict):
-            for key in other:
-                self[key] = other[key]
-        elif hasattr(other, 'keys'):
-            for key in other.keys():
-                self[key] = other[key]
-        else:
-            for key, value in other:
-                self[key] = value
-        for key, value in kwds.items():
-            self[key] = value
-
-    __update = update  # let subclasses override update without breaking __init__
-
-    __marker = object()
-
-    def pop(self, key, default=__marker):
-        '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
-        If key is not found, d is returned if given, otherwise KeyError is raised.
-
-        '''
-        if key in self:
-            result = self[key]
-            del self[key]
-            return result
-        if default is self.__marker:
-            raise KeyError(key)
-        return default
-
-    def setdefault(self, key, default=None):
-        'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
-        if key in self:
-            return self[key]
-        self[key] = default
-        return default
-
-    def __repr__(self, _repr_running={}):
-        'od.__repr__() <==> repr(od)'
-        call_key = id(self), _get_ident()
-        if call_key in _repr_running:
-            return '...'
-        _repr_running[call_key] = 1
-        try:
-            if not self:
-                return '%s()' % (self.__class__.__name__,)
-            return '%s(%r)' % (self.__class__.__name__, self.items())
-        finally:
-            del _repr_running[call_key]
-
-    def __reduce__(self):
-        'Return state information for pickling'
-        items = [[k, self[k]] for k in self]
-        inst_dict = vars(self).copy()
-        for k in vars(OrderedDict()):
-            inst_dict.pop(k, None)
-        if inst_dict:
-            return (self.__class__, (items,), inst_dict)
-        return self.__class__, (items,)
-
-    def copy(self):
-        'od.copy() -> a shallow copy of od'
-        return self.__class__(self)
-
-    @classmethod
-    def fromkeys(cls, iterable, value=None):
-        '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
-        and values equal to v (which defaults to None).
-
-        '''
-        d = cls()
-        for key in iterable:
-            d[key] = value
-        return d
-
-    def __eq__(self, other):
-        '''od.__eq__(y) <==> od==y.  Comparison to another OD is order-sensitive
-        while comparison to a regular mapping is order-insensitive.
-
-        '''
-        if isinstance(other, OrderedDict):
-            return len(self)==len(other) and self.items() == other.items()
-        return dict.__eq__(self, other)
-
-    def __ne__(self, other):
-        return not self == other
-
-    # -- the following methods are only used in Python 2.7 --
-
-    def viewkeys(self):
-        "od.viewkeys() -> a set-like object providing a view on od's keys"
-        return KeysView(self)
-
-    def viewvalues(self):
-        "od.viewvalues() -> an object providing a view on od's values"
-        return ValuesView(self)
-
-    def viewitems(self):
-        "od.viewitems() -> a set-like object providing a view on od's items"
-        return ItemsView(self)
diff --git a/funcsigs/version.py b/funcsigs/version.py
deleted file mode 100644
index 896a370..0000000
--- a/funcsigs/version.py
+++ /dev/null
@@ -1 +0,0 @@
-__version__ = "0.4"
diff --git a/requirements/development.txt b/requirements/development.txt
deleted file mode 100644
index ecafb0a..0000000
--- a/requirements/development.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-coverage
-coveralls
-pip
-flake8
-sphinx
-wheel
diff --git a/requirements/production.txt b/requirements/production.txt
deleted file mode 100644
index e69de29..0000000
--- a/requirements/production.txt
+++ /dev/null
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 5e40900..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[wheel]
-universal = 1
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 98b0912..0000000
--- a/setup.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-from setuptools import setup
-import re
-import sys
-
-def load_version(filename='funcsigs/version.py'):
-    "Parse a __version__ number from a source file"
-    with open(filename) as source:
-        text = source.read()
-        match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", text)
-        if not match:
-            msg = "Unable to find version number in {}".format(filename)
-            raise RuntimeError(msg)
-        version = match.group(1)
-        return version
-
-def load_rst(filename='docs/source/guide_content.rst'):
-    "Purge refs directives from restructured text"
-    with open(filename) as source:
-        text = source.read()
-        doc = re.sub(r':\w+:`~?([a-zA-Z._()]+)`', r'*\1*', text)
-        return doc
-
-setup(
-    name="funcsigs",
-    version=load_version(),
-    packages=['funcsigs'],
-    zip_safe=False,
-    author="Aaron Iles",
-    author_email="aaron.iles@gmail.com",
-    url="http://funcsigs.readthedocs.org",
-    description="Python function signatures from PEP362 for Python 2.6, 2.7 and 3.2+",
-    long_description=open('README.rst').read(),
-    # long_description=load_rst(),
-    license="ASL",
-    install_requires = [],
-    classifiers = [
-        'Development Status :: 4 - Beta',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: Apache Software License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.6',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.2',
-        'Programming Language :: Python :: 3.3',
-        'Programming Language :: Python :: Implementation :: CPython',
-        'Programming Language :: Python :: Implementation :: PyPy',
-        'Topic :: Software Development :: Libraries :: Python Modules'
-    ],
-    tests_require = [] if sys.version_info[0] > 2 else ['unittest2'],
-    test_suite = "tests" if sys.version_info[0] > 2 else 'unittest2.collector'
-)
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tests/__init__.py
+++ /dev/null
diff --git a/tests/test_formatannotation.py b/tests/test_formatannotation.py
deleted file mode 100644
index fd7a887..0000000
--- a/tests/test_formatannotation.py
+++ /dev/null
@@ -1,27 +0,0 @@
-try:
-    # python 2.x
-    import unittest2 as unittest
-except ImportError:
-    # python 3.x
-    import unittest
-
-import funcsigs
-
-
-class TestFormatAnnotation(unittest.TestCase):
-    def test_string (self):
-        self.assertEqual(funcsigs.formatannotation("annotation"),
-                         "'annotation'")
-
-    def test_builtin_type (self):
-        self.assertEqual(funcsigs.formatannotation(int),
-                         "int")
-
-    def test_user_type (self):
-        class dummy (object): pass
-        self.assertEqual(funcsigs.formatannotation(dummy),
-                         "tests.test_formatannotation.dummy")
-
-
-if __name__ == "__main__":
-    unittest.begin()
diff --git a/tests/test_funcsigs.py b/tests/test_funcsigs.py
deleted file mode 100644
index eecc0a8..0000000
--- a/tests/test_funcsigs.py
+++ /dev/null
@@ -1,93 +0,0 @@
-try:
-    # python 2.x
-    import unittest2 as unittest
-except ImportError:
-    # python 3.x
-    import unittest
-
-import doctest
-import sys
-
-import funcsigs as inspect
-
-
-class TestFunctionSignatures(unittest.TestCase):
-
-    @staticmethod
-    def signature(func):
-        sig = inspect.signature(func)
-        return (tuple((param.name,
-                       (Ellipsis if param.default is param.empty else param.default),
-                       (Ellipsis if param.annotation is param.empty
-                                                        else param.annotation),
-                       str(param.kind).lower())
-                                    for param in sig.parameters.values()),
-                (Ellipsis if sig.return_annotation is sig.empty
-                                            else sig.return_annotation))
-
-    def test_zero_arguments(self):
-        def test():
-            pass
-        self.assertEqual(self.signature(test),
-                ((), Ellipsis))
-
-    def test_single_positional_argument(self):
-        def test(a):
-            pass
-        self.assertEqual(self.signature(test),
-                (((('a', Ellipsis, Ellipsis, "positional_or_keyword")),), Ellipsis))
-
-    def test_single_keyword_argument(self):
-        def test(a=None):
-            pass
-        self.assertEqual(self.signature(test),
-                (((('a', None, Ellipsis, "positional_or_keyword")),), Ellipsis))
-
-    def test_var_args(self):
-        def test(*args):
-            pass
-        self.assertEqual(self.signature(test),
-                (((('args', Ellipsis, Ellipsis, "var_positional")),), Ellipsis))
-
-    def test_keywords_args(self):
-        def test(**kwargs):
-            pass
-        self.assertEqual(self.signature(test),
-                (((('kwargs', Ellipsis, Ellipsis, "var_keyword")),), Ellipsis))
-
-    def test_multiple_arguments(self):
-        def test(a, b=None, *args, **kwargs):
-            pass
-        self.assertEqual(self.signature(test), ((
-            ('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-            ('b', None, Ellipsis, "positional_or_keyword"),
-            ('args', Ellipsis, Ellipsis, "var_positional"),
-            ('kwargs', Ellipsis, Ellipsis, "var_keyword"),
-            ), Ellipsis))
-
-    def test_has_version(self):
-        self.assertTrue(inspect.__version__)
-
-    def test_readme(self):
-        doctest.testfile('../README.rst')
-
-    def test_unbound_method(self):
-        if sys.version_info < (3,):
-            self_kind = "positional_only"
-        else:
-            self_kind = "positional_or_keyword"
-        class Test(object):
-            def method(self):
-                pass
-            def method_with_args(self, a):
-                pass
-        self.assertEqual(self.signature(Test.method),
-                (((('self', Ellipsis, Ellipsis, self_kind)),), Ellipsis))
-        self.assertEqual(self.signature(Test.method_with_args), ((
-                ('self', Ellipsis, Ellipsis, self_kind),
-                ('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                ), Ellipsis))
-
-
-if __name__ == "__main__":
-    unittest.begin()
diff --git a/tests/test_inspect.py b/tests/test_inspect.py
deleted file mode 100644
index 323c323..0000000
--- a/tests/test_inspect.py
+++ /dev/null
@@ -1,1019 +0,0 @@
-# Copyright 2001-2013 Python Software Foundation; All Rights Reserved
-from __future__ import absolute_import, division, print_function
-import collections
-import sys
-
-try:
-    import unittest2 as unittest
-except ImportError:
-    import unittest
-
-import funcsigs as inspect
-
-
-class TestSignatureObject(unittest.TestCase):
-    @staticmethod
-    def signature(func):
-        sig = inspect.signature(func)
-        return (tuple((param.name,
-                       (Ellipsis if param.default is param.empty else param.default),
-                       (Ellipsis if param.annotation is param.empty
-                                                        else param.annotation),
-                       str(param.kind).lower())
-                                    for param in sig.parameters.values()),
-                (Ellipsis if sig.return_annotation is sig.empty
-                                            else sig.return_annotation))
-
-    def __init__(self, *args, **kwargs):
-        unittest.TestCase.__init__(self, *args, **kwargs)
-        if not hasattr(self, 'assertRaisesRegex'):
-            self.assertRaisesRegex = self.assertRaisesRegexp
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_object(self):
-    S = inspect.Signature
-    P = inspect.Parameter
-
-    self.assertEqual(str(S()), '()')
-
-    def test(po, pk, *args, ko, **kwargs):
-        pass
-    sig = inspect.signature(test)
-    po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
-    pk = sig.parameters['pk']
-    args = sig.parameters['args']
-    ko = sig.parameters['ko']
-    kwargs = sig.parameters['kwargs']
-
-    S((po, pk, args, ko, kwargs))
-
-    with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
-        S((pk, po, args, ko, kwargs))
-
-    with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
-        S((po, args, pk, ko, kwargs))
-
-    with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
-        S((args, po, pk, ko, kwargs))
-
-    with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
-        S((po, pk, args, kwargs, ko))
-
-    kwargs2 = kwargs.replace(name='args')
-    with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
-        S((po, pk, args, kwargs2, ko))
-""")
-
-    def test_signature_immutability(self):
-        def test(a):
-            pass
-        sig = inspect.signature(test)
-
-        with self.assertRaises(AttributeError):
-            sig.foo = 'bar'
-
-        # Python2 does not have MappingProxyType class
-        if sys.version_info[:2] < (3, 3):
-            return
-
-        with self.assertRaises(TypeError):
-            sig.parameters['a'] = None
-
-    def test_signature_on_noarg(self):
-        def test():
-            pass
-        self.assertEqual(self.signature(test), ((), Ellipsis))
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_wargs(self):
-    def test(a, b:'foo') -> 123:
-        pass
-    self.assertEqual(self.signature(test),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', Ellipsis, 'foo', "positional_or_keyword")),
-                      123))
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_wkwonly(self):
-    def test(*, a:float, b:str) -> int:
-        pass
-    self.assertEqual(self.signature(test),
-                     ((('a', Ellipsis, float, "keyword_only"),
-                       ('b', Ellipsis, str, "keyword_only")),
-                       int))
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_complex_args(self):
-    def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
-        pass
-    self.assertEqual(self.signature(test),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', 10, 'foo', "positional_or_keyword"),
-                       ('args', Ellipsis, 'bar', "var_positional"),
-                       ('spam', Ellipsis, 'baz', "keyword_only"),
-                       ('ham', 123, Ellipsis, "keyword_only"),
-                       ('kwargs', Ellipsis, int, "var_keyword")),
-                      Ellipsis))
-""")
-
-    def test_signature_on_builtin_function(self):
-        with self.assertRaisesRegex(ValueError, 'not supported by signature'):
-            inspect.signature(type)
-        with self.assertRaisesRegex(ValueError, 'not supported by signature'):
-            # support for 'wrapper_descriptor'
-            inspect.signature(type.__call__)
-            if hasattr(sys, 'pypy_version_info'):
-                raise ValueError('not supported by signature')
-        with self.assertRaisesRegex(ValueError, 'not supported by signature'):
-            # support for 'method-wrapper'
-            inspect.signature(min.__call__)
-            if hasattr(sys, 'pypy_version_info'):
-                raise ValueError('not supported by signature')
-        with self.assertRaisesRegex(ValueError,
-                                     'no signature found for builtin function'):
-            # support for 'method-wrapper'
-            inspect.signature(min)
-
-    def test_signature_on_non_function(self):
-        with self.assertRaisesRegex(TypeError, 'is not a callable object'):
-            inspect.signature(42)
-
-        with self.assertRaisesRegex(TypeError, 'is not a Python function'):
-            inspect.Signature.from_function(42)
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_method(self):
-    class Test:
-        def foo(self, arg1, arg2=1) -> int:
-            pass
-
-    meth = Test().foo
-
-    self.assertEqual(self.signature(meth),
-                     ((('arg1', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('arg2', 1, Ellipsis, "positional_or_keyword")),
-                      int))
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_classmethod(self):
-    class Test:
-        @classmethod
-        def foo(cls, arg1, *, arg2=1):
-            pass
-
-    meth = Test().foo
-    self.assertEqual(self.signature(meth),
-                     ((('arg1', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('arg2', 1, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    meth = Test.foo
-    self.assertEqual(self.signature(meth),
-                     ((('arg1', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('arg2', 1, Ellipsis, "keyword_only")),
-                      Ellipsis))
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_staticmethod(self):
-    class Test:
-        @staticmethod
-        def foo(cls, *, arg):
-            pass
-
-    meth = Test().foo
-    self.assertEqual(self.signature(meth),
-                     ((('cls', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('arg', Ellipsis, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    meth = Test.foo
-    self.assertEqual(self.signature(meth),
-                     ((('cls', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('arg', Ellipsis, Ellipsis, "keyword_only")),
-                      Ellipsis))
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_partial(self):
-    from functools import partial
-
-    def test():
-        pass
-
-    self.assertEqual(self.signature(partial(test)), ((), Ellipsis))
-
-    with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
-        inspect.signature(partial(test, 1))
-
-    with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
-        inspect.signature(partial(test, a=1))
-
-    def test(a, b, *, c, d):
-        pass
-
-    self.assertEqual(self.signature(partial(test)),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('c', Ellipsis, Ellipsis, "keyword_only"),
-                       ('d', Ellipsis, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, 1)),
-                     ((('b', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('c', Ellipsis, Ellipsis, "keyword_only"),
-                       ('d', Ellipsis, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, 1, c=2)),
-                     ((('b', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('c', 2, Ellipsis, "keyword_only"),
-                       ('d', Ellipsis, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, b=1, c=2)),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', 1, Ellipsis, "positional_or_keyword"),
-                       ('c', 2, Ellipsis, "keyword_only"),
-                       ('d', Ellipsis, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
-                     ((('b', 1, Ellipsis, "positional_or_keyword"),
-                       ('c', 2, Ellipsis, "keyword_only"),
-                       ('d', Ellipsis, Ellipsis, "keyword_only"),),
-                      Ellipsis))
-
-    def test(a, *args, b, **kwargs):
-        pass
-
-    self.assertEqual(self.signature(partial(test, 1)),
-                     ((('args', Ellipsis, Ellipsis, "var_positional"),
-                       ('b', Ellipsis, Ellipsis, "keyword_only"),
-                       ('kwargs', Ellipsis, Ellipsis, "var_keyword")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, 1, 2, 3)),
-                     ((('args', Ellipsis, Ellipsis, "var_positional"),
-                       ('b', Ellipsis, Ellipsis, "keyword_only"),
-                       ('kwargs', Ellipsis, Ellipsis, "var_keyword")),
-                      Ellipsis))
-
-
-    self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
-                     ((('args', Ellipsis, Ellipsis, "var_positional"),
-                       ('b', Ellipsis, Ellipsis, "keyword_only"),
-                       ('kwargs', Ellipsis, Ellipsis, "var_keyword")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
-                     ((('args', Ellipsis, Ellipsis, "var_positional"),
-                       ('b', 0, Ellipsis, "keyword_only"),
-                       ('kwargs', Ellipsis, Ellipsis, "var_keyword")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, b=0)),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('args', Ellipsis, Ellipsis, "var_positional"),
-                       ('b', 0, Ellipsis, "keyword_only"),
-                       ('kwargs', Ellipsis, Ellipsis, "var_keyword")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(partial(test, b=0, test=1)),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('args', Ellipsis, Ellipsis, "var_positional"),
-                       ('b', 0, Ellipsis, "keyword_only"),
-                       ('kwargs', Ellipsis, Ellipsis, "var_keyword")),
-                      Ellipsis))
-
-    def test(a, b, c:int) -> 42:
-        pass
-
-    sig = test.__signature__ = inspect.signature(test)
-
-    self.assertEqual(self.signature(partial(partial(test, 1))),
-                     ((('b', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('c', Ellipsis, int, "positional_or_keyword")),
-                      42))
-
-    self.assertEqual(self.signature(partial(partial(test, 1), 2)),
-                     ((('c', Ellipsis, int, "positional_or_keyword"),),
-                      42))
-
-    psig = inspect.signature(partial(partial(test, 1), 2))
-
-    def foo(a):
-        return a
-    _foo = partial(partial(foo, a=10), a=20)
-    self.assertEqual(self.signature(_foo),
-                     ((('a', 20, Ellipsis, "positional_or_keyword"),),
-                      Ellipsis))
-    # check that we don't have any side-effects in signature(),
-    # and the partial object is still functioning
-    self.assertEqual(_foo(), 20)
-
-    def foo(a, b, c):
-        return a, b, c
-    _foo = partial(partial(foo, 1, b=20), b=30)
-    self.assertEqual(self.signature(_foo),
-                     ((('b', 30, Ellipsis, "positional_or_keyword"),
-                       ('c', Ellipsis, Ellipsis, "positional_or_keyword")),
-                      Ellipsis))
-    self.assertEqual(_foo(c=10), (1, 30, 10))
-    _foo = partial(_foo, 2) # now 'b' has two values -
-                            # positional and keyword
-    with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
-        inspect.signature(_foo)
-
-    def foo(a, b, c, *, d):
-        return a, b, c, d
-    _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
-    self.assertEqual(self.signature(_foo),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', 10, Ellipsis, "positional_or_keyword"),
-                       ('c', 20, Ellipsis, "positional_or_keyword"),
-                       ('d', 30, Ellipsis, "keyword_only")),
-                      Ellipsis))
-    ba = inspect.signature(_foo).bind(a=200, b=11)
-    self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
-
-    def foo(a=1, b=2, c=3):
-        return a, b, c
-    _foo = partial(foo, a=10, c=13)
-    ba = inspect.signature(_foo).bind(11)
-    self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
-    ba = inspect.signature(_foo).bind(11, 12)
-    self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
-    ba = inspect.signature(_foo).bind(11, b=12)
-    self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
-    ba = inspect.signature(_foo).bind(b=12)
-    self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13))
-    _foo = partial(_foo, b=10)
-    ba = inspect.signature(_foo).bind(12, 14)
-    self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13))
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_decorated(self):
-    import functools
-
-    def decorator(func):
-        @functools.wraps(func)
-        def wrapper(*args, **kwargs) -> int:
-            return func(*args, **kwargs)
-        return wrapper
-
-    class Foo:
-        @decorator
-        def bar(self, a, b):
-            pass
-
-    self.assertEqual(self.signature(Foo.bar),
-                     ((('self', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', Ellipsis, Ellipsis, "positional_or_keyword")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(Foo().bar),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', Ellipsis, Ellipsis, "positional_or_keyword")),
-                      Ellipsis))
-
-    # Test that we handle method wrappers correctly
-    def decorator(func):
-        @functools.wraps(func)
-        def wrapper(*args, **kwargs) -> int:
-            return func(42, *args, **kwargs)
-        sig = inspect.signature(func)
-        new_params = tuple(sig.parameters.values())[1:]
-        wrapper.__signature__ = sig.replace(parameters=new_params)
-        return wrapper
-
-    class Foo:
-        @decorator
-        def __call__(self, a, b):
-            pass
-
-    self.assertEqual(self.signature(Foo.__call__),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('b', Ellipsis, Ellipsis, "positional_or_keyword")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(Foo().__call__),
-                     ((('b', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                      Ellipsis))
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_on_class(self):
-    class C:
-        def __init__(self, a):
-            pass
-
-    self.assertEqual(self.signature(C),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                      Ellipsis))
-
-    class CM(type):
-        def __call__(cls, a):
-            pass
-    class C(metaclass=CM):
-        def __init__(self, b):
-            pass
-
-    self.assertEqual(self.signature(C),
-                     ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                      Ellipsis))
-
-    class CM(type):
-        def __new__(mcls, name, bases, dct, *, foo=1):
-            return super().__new__(mcls, name, bases, dct)
-    class C(metaclass=CM):
-        def __init__(self, b):
-            pass
-
-    self.assertEqual(self.signature(C),
-                     ((('b', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(CM),
-                     ((('name', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('bases', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('dct', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('foo', 1, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    class CMM(type):
-        def __new__(mcls, name, bases, dct, *, foo=1):
-            return super().__new__(mcls, name, bases, dct)
-        def __call__(cls, nm, bs, dt):
-            return type(nm, bs, dt)
-    class CM(type, metaclass=CMM):
-        def __new__(mcls, name, bases, dct, *, bar=2):
-            return super().__new__(mcls, name, bases, dct)
-    class C(metaclass=CM):
-        def __init__(self, b):
-            pass
-
-    self.assertEqual(self.signature(CMM),
-                     ((('name', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('bases', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('dct', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('foo', 1, Ellipsis, "keyword_only")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(CM),
-                     ((('nm', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('bs', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('dt', Ellipsis, Ellipsis, "positional_or_keyword")),
-                      Ellipsis))
-
-    self.assertEqual(self.signature(C),
-                     ((('b', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                      Ellipsis))
-
-    class CM(type):
-        def __init__(cls, name, bases, dct, *, bar=2):
-            return super().__init__(name, bases, dct)
-    class C(metaclass=CM):
-        def __init__(self, b):
-            pass
-
-    self.assertEqual(self.signature(CM),
-                     ((('name', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('bases', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('dct', Ellipsis, Ellipsis, "positional_or_keyword"),
-                       ('bar', 2, Ellipsis, "keyword_only")),
-                      Ellipsis))
-""")
-
-    def test_signature_on_callable_objects(self):
-        class Foo(object):
-            def __call__(self, a):
-                pass
-
-        self.assertEqual(self.signature(Foo()),
-                         ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                          Ellipsis))
-
-        class Spam(object):
-            pass
-        with self.assertRaisesRegex(TypeError, "is not a callable object"):
-            inspect.signature(Spam())
-
-        class Bar(Spam, Foo):
-            pass
-
-        self.assertEqual(self.signature(Bar()),
-                         ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                          Ellipsis))
-
-        class ToFail(object):
-            __call__ = type
-        with self.assertRaisesRegex(ValueError, "not supported by signature"):
-            inspect.signature(ToFail())
-
-        if sys.version_info[0] < 3:
-            return
-
-        class Wrapped(object):
-            pass
-        Wrapped.__wrapped__ = lambda a: None
-        self.assertEqual(self.signature(Wrapped),
-                         ((('a', Ellipsis, Ellipsis, "positional_or_keyword"),),
-                          Ellipsis))
-
-    def test_signature_on_lambdas(self):
-        self.assertEqual(self.signature((lambda a=10: a)),
-                         ((('a', 10, Ellipsis, "positional_or_keyword"),),
-                          Ellipsis))
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_equality(self):
-    def foo(a, *, b:int) -> float: pass
-    self.assertNotEqual(inspect.signature(foo), 42)
-
-    def bar(a, *, b:int) -> float: pass
-    self.assertEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def bar(a, *, b:int) -> int: pass
-    self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def bar(a, *, b:int): pass
-    self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def bar(a, *, b:int=42) -> float: pass
-    self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def bar(a, *, c) -> float: pass
-    self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def bar(a, b:int) -> float: pass
-    self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
-    def spam(b:int, a) -> float: pass
-    self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))
-
-    def foo(*, a, b, c): pass
-    def bar(*, c, b, a): pass
-    self.assertEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def foo(*, a=1, b, c): pass
-    def bar(*, c, b, a=1): pass
-    self.assertEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def foo(pos, *, a=1, b, c): pass
-    def bar(pos, *, c, b, a=1): pass
-    self.assertEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def foo(pos, *, a, b, c): pass
-    def bar(pos, *, c, b, a=1): pass
-    self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
-
-    def foo(pos, *args, a=42, b, c, **kwargs:int): pass
-    def bar(pos, *args, c, b, a=42, **kwargs:int): pass
-    self.assertEqual(inspect.signature(foo), inspect.signature(bar))
-""")
-
-    def test_signature_unhashable(self):
-        def foo(a): pass
-        sig = inspect.signature(foo)
-        with self.assertRaisesRegex(TypeError, 'unhashable type'):
-            hash(sig)
-
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_str(self):
-    def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
-        pass
-    self.assertEqual(str(inspect.signature(foo)),
-                     '(a:int=1, *, b, c=None, **kwargs) -> 42')
-
-    def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
-        pass
-    self.assertEqual(str(inspect.signature(foo)),
-                     '(a:int=1, *args, b, c=None, **kwargs) -> 42')
-
-    def foo():
-        pass
-    self.assertEqual(str(inspect.signature(foo)), '()')
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_str_positional_only(self):
-    P = inspect.Parameter
-
-    def test(a_po, *, b, **kwargs):
-        return a_po, kwargs
-
-    sig = inspect.signature(test)
-    new_params = list(sig.parameters.values())
-    new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
-    test.__signature__ = sig.replace(parameters=new_params)
-
-    self.assertEqual(str(inspect.signature(test)),
-                     '(<a_po>, *, b, **kwargs)')
-
-    sig = inspect.signature(test)
-    new_params = list(sig.parameters.values())
-    new_params[0] = new_params[0].replace(name=None)
-    test.__signature__ = sig.replace(parameters=new_params)
-    self.assertEqual(str(inspect.signature(test)),
-                     '(<0>, *, b, **kwargs)')
-""")
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_replace_anno(self):
-    def test() -> 42:
-        pass
-
-    sig = inspect.signature(test)
-    sig = sig.replace(return_annotation=None)
-    self.assertIs(sig.return_annotation, None)
-    sig = sig.replace(return_annotation=sig.empty)
-    self.assertIs(sig.return_annotation, sig.empty)
-    sig = sig.replace(return_annotation=42)
-    self.assertEqual(sig.return_annotation, 42)
-    self.assertEqual(sig, inspect.signature(test))
-""")
-
-
-class TestParameterObject(unittest.TestCase):
-
-    def __init__(self, *args, **kwargs):
-        unittest.TestCase.__init__(self, *args, **kwargs)
-        if not hasattr(self, 'assertRaisesRegex'):
-            self.assertRaisesRegex = self.assertRaisesRegexp
-
-    def test_signature_parameter_kinds(self):
-        P = inspect.Parameter
-        self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
-                        P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
-
-        self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
-        self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
-
-    def test_signature_parameter_object(self):
-        p = inspect.Parameter('foo', default=10,
-                              kind=inspect.Parameter.POSITIONAL_ONLY)
-        self.assertEqual(p.name, 'foo')
-        self.assertEqual(p.default, 10)
-        self.assertIs(p.annotation, p.empty)
-        self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
-
-        with self.assertRaisesRegex(ValueError, 'invalid value'):
-            inspect.Parameter('foo', default=10, kind='123')
-
-        with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
-            inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
-
-        with self.assertRaisesRegex(ValueError,
-                                     'non-positional-only parameter'):
-            inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
-
-        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
-            inspect.Parameter('a', default=42,
-                              kind=inspect.Parameter.VAR_KEYWORD)
-
-        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
-            inspect.Parameter('a', default=42,
-                              kind=inspect.Parameter.VAR_POSITIONAL)
-
-        p = inspect.Parameter('a', default=42,
-                              kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
-        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
-            p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
-
-        self.assertTrue(repr(p).startswith('<Parameter'))
-
-    def test_signature_parameter_equality(self):
-        P = inspect.Parameter
-        p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
-
-        self.assertEqual(p, p)
-        self.assertNotEqual(p, 42)
-
-        self.assertEqual(p, P('foo', default=42,
-                              kind=inspect.Parameter.KEYWORD_ONLY))
-
-    def test_signature_parameter_unhashable(self):
-        p = inspect.Parameter('foo', default=42,
-                              kind=inspect.Parameter.KEYWORD_ONLY)
-
-        with self.assertRaisesRegex(TypeError, 'unhashable type'):
-            hash(p)
-
-    def test_signature_parameter_replace(self):
-        p = inspect.Parameter('foo', default=42,
-                              kind=inspect.Parameter.KEYWORD_ONLY)
-
-        self.assertIsNot(p, p.replace())
-        self.assertEqual(p, p.replace())
-
-        p2 = p.replace(annotation=1)
-        self.assertEqual(p2.annotation, 1)
-        p2 = p2.replace(annotation=p2.empty)
-        self.assertEqual(p, p2)
-
-        p2 = p2.replace(name='bar')
-        self.assertEqual(p2.name, 'bar')
-        self.assertNotEqual(p2, p)
-
-        with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
-            p2 = p2.replace(name=p2.empty)
-
-        p2 = p2.replace(name='foo', default=None)
-        self.assertIs(p2.default, None)
-        self.assertNotEqual(p2, p)
-
-        p2 = p2.replace(name='foo', default=p2.empty)
-        self.assertIs(p2.default, p2.empty)
-
-
-        p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
-        self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
-        self.assertNotEqual(p2, p)
-
-        with self.assertRaisesRegex(ValueError, 'invalid value for'):
-            p2 = p2.replace(kind=p2.empty)
-
-        p2 = p2.replace(kind=p2.KEYWORD_ONLY)
-        self.assertEqual(p2, p)
-
-    def test_signature_parameter_positional_only(self):
-        p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
-        self.assertEqual(str(p), '<>')
-
-        p = p.replace(name='1')
-        self.assertEqual(str(p), '<1>')
-
-    def test_signature_parameter_immutability(self):
-        p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
-
-        with self.assertRaises(AttributeError):
-            p.foo = 'bar'
-
-        with self.assertRaises(AttributeError):
-            p.kind = 123
-
-
-class TestSignatureBind(unittest.TestCase):
-    @staticmethod
-    def call(func, *args, **kwargs):
-        sig = inspect.signature(func)
-        ba = sig.bind(*args, **kwargs)
-        return func(*ba.args, **ba.kwargs)
-
-    def __init__(self, *args, **kwargs):
-        unittest.TestCase.__init__(self, *args, **kwargs)
-        if not hasattr(self, 'assertRaisesRegex'):
-            self.assertRaisesRegex = self.assertRaisesRegexp
-
-    def test_signature_bind_empty(self):
-        def test():
-            return 42
-
-        self.assertEqual(self.call(test), 42)
-        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
-            self.call(test, 1)
-        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
-            self.call(test, 1, spam=10)
-        with self.assertRaisesRegex(TypeError, 'too many keyword arguments'):
-            self.call(test, spam=1)
-
-    def test_signature_bind_var(self):
-        def test(*args, **kwargs):
-            return args, kwargs
-
-        self.assertEqual(self.call(test), ((), {}))
-        self.assertEqual(self.call(test, 1), ((1,), {}))
-        self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
-        self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
-        self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
-        self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
-        self.assertEqual(self.call(test, 1, 2, foo='bar'),
-                         ((1, 2), {'foo': 'bar'}))
-
-    def test_signature_bind_just_args(self):
-        def test(a, b, c):
-            return a, b, c
-
-        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
-
-        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
-            self.call(test, 1, 2, 3, 4)
-
-        with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"):
-            self.call(test, 1)
-
-        with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"):
-            self.call(test)
-
-        def test(a, b, c=10):
-            return a, b, c
-        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
-        self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
-
-        def test(a=1, b=2, c=3):
-            return a, b, c
-        self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
-        self.assertEqual(self.call(test, a=10), (10, 2, 3))
-        self.assertEqual(self.call(test, b=10), (1, 10, 3))
-
-    def test_signature_bind_varargs_order(self):
-        def test(*args):
-            return args
-
-        self.assertEqual(self.call(test), ())
-        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
-
-    def test_signature_bind_args_and_varargs(self):
-        def test(a, b, c=3, *args):
-            return a, b, c, args
-
-        self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
-        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
-        self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
-        self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
-
-        with self.assertRaisesRegex(TypeError,
-                                     "multiple values for argument 'c'"):
-            self.call(test, 1, 2, 3, c=4)
-
-    def test_signature_bind_just_kwargs(self):
-        def test(**kwargs):
-            return kwargs
-
-        self.assertEqual(self.call(test), {})
-        self.assertEqual(self.call(test, foo='bar', spam='ham'),
-                         {'foo': 'bar', 'spam': 'ham'})
-
-    def test_signature_bind_args_and_kwargs(self):
-        def test(a, b, c=3, **kwargs):
-            return a, b, c, kwargs
-
-        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
-        self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
-                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
-        self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
-                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
-        self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
-                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
-        self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
-                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
-        self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
-                         (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
-        self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
-                         (1, 2, 4, {'foo': 'bar'}))
-        self.assertEqual(self.call(test, c=5, a=4, b=3),
-                         (4, 3, 5, {}))
-
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_bind_kwonly(self):
-    def test(*, foo):
-        return foo
-    with self.assertRaisesRegex(TypeError,
-                                 'too many positional arguments'):
-        self.call(test, 1)
-    self.assertEqual(self.call(test, foo=1), 1)
-
-    def test(a, *, foo=1, bar):
-        return foo
-    with self.assertRaisesRegex(TypeError,
-                                 "'bar' parameter lacking default value"):
-        self.call(test, 1)
-
-    def test(foo, *, bar):
-        return foo, bar
-    self.assertEqual(self.call(test, 1, bar=2), (1, 2))
-    self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
-
-    with self.assertRaisesRegex(TypeError,
-                                 'too many keyword arguments'):
-        self.call(test, bar=2, foo=1, spam=10)
-
-    with self.assertRaisesRegex(TypeError,
-                                 'too many positional arguments'):
-        self.call(test, 1, 2)
-
-    with self.assertRaisesRegex(TypeError,
-                                 'too many positional arguments'):
-        self.call(test, 1, 2, bar=2)
-
-    with self.assertRaisesRegex(TypeError,
-                                 'too many keyword arguments'):
-        self.call(test, 1, bar=2, spam='ham')
-
-    with self.assertRaisesRegex(TypeError,
-                                 "'bar' parameter lacking default value"):
-        self.call(test, 1)
-
-    def test(foo, *, bar, **bin):
-        return foo, bar, bin
-    self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
-    self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
-    self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
-                     (1, 2, {'spam': 'ham'}))
-    self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
-                     (1, 2, {'spam': 'ham'}))
-    with self.assertRaisesRegex(TypeError,
-                                 "'foo' parameter lacking default value"):
-        self.call(test, spam='ham', bar=2)
-    self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
-                     (1, 2, {'bin': 1, 'spam': 10}))
-""")
-#
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_bind_arguments(self):
-    def test(a, *args, b, z=100, **kwargs):
-        pass
-    sig = inspect.signature(test)
-    ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
-    # we won't have 'z' argument in the bound arguments object, as we didn't
-    # pass it to the 'bind'
-    self.assertEqual(tuple(ba.arguments.items()),
-                     (('a', 10), ('args', (20,)), ('b', 30),
-                      ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
-    self.assertEqual(ba.kwargs,
-                     {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
-    self.assertEqual(ba.args, (10, 20))
-""")
-#
-    if sys.version_info[0] > 2:
-        exec("""
-def test_signature_bind_positional_only(self):
-    P = inspect.Parameter
-
-    def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
-        return a_po, b_po, c_po, foo, bar, kwargs
-
-    sig = inspect.signature(test)
-    new_params = collections.OrderedDict(tuple(sig.parameters.items()))
-    for name in ('a_po', 'b_po', 'c_po'):
-        new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
-    new_sig = sig.replace(parameters=new_params.values())
-    test.__signature__ = new_sig
-
-    self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
-                     (1, 2, 4, 5, 6, {}))
-
-    with self.assertRaisesRegex(TypeError, "parameter is positional only"):
-        self.call(test, 1, 2, c_po=4)
-
-    with self.assertRaisesRegex(TypeError, "parameter is positional only"):
-        self.call(test, a_po=1, b_po=2)
-""")
-
-
-class TestBoundArguments(unittest.TestCase):
-
-    def __init__(self, *args, **kwargs):
-        unittest.TestCase.__init__(self, *args, **kwargs)
-        if not hasattr(self, 'assertRaisesRegex'):
-            self.assertRaisesRegex = self.assertRaisesRegexp
-
-    def test_signature_bound_arguments_unhashable(self):
-        def foo(a): pass
-        ba = inspect.signature(foo).bind(1)
-
-        with self.assertRaisesRegex(TypeError, 'unhashable type'):
-            hash(ba)
-
-    def test_signature_bound_arguments_equality(self):
-        def foo(a): pass
-        ba = inspect.signature(foo).bind(1)
-        self.assertEqual(ba, ba)
-
-        ba2 = inspect.signature(foo).bind(1)
-        self.assertEqual(ba, ba2)
-
-        ba3 = inspect.signature(foo).bind(2)
-        self.assertNotEqual(ba, ba3)
-        ba3.arguments['a'] = 1
-        self.assertEqual(ba, ba3)
-
-        def bar(b): pass
-        ba4 = inspect.signature(bar).bind(1)
-        self.assertNotEqual(ba, ba4)
-
-
-if __name__ == "__main__":
-    unittest.begin()