summaryrefslogtreecommitdiff
path: root/test/3rdparty/extras-0.0.3
diff options
context:
space:
mode:
Diffstat (limited to 'test/3rdparty/extras-0.0.3')
-rw-r--r--test/3rdparty/extras-0.0.3/.gitignore35
-rw-r--r--test/3rdparty/extras-0.0.3/LICENSE26
-rw-r--r--test/3rdparty/extras-0.0.3/MANIFEST.in6
-rw-r--r--test/3rdparty/extras-0.0.3/Makefile30
-rw-r--r--test/3rdparty/extras-0.0.3/NEWS27
-rw-r--r--test/3rdparty/extras-0.0.3/PKG-INFO68
-rw-r--r--test/3rdparty/extras-0.0.3/README.rst57
-rw-r--r--test/3rdparty/extras-0.0.3/extras.egg-info/PKG-INFO68
-rw-r--r--test/3rdparty/extras-0.0.3/extras.egg-info/SOURCES.txt15
-rw-r--r--test/3rdparty/extras-0.0.3/extras.egg-info/dependency_links.txt1
-rw-r--r--test/3rdparty/extras-0.0.3/extras.egg-info/top_level.txt1
-rw-r--r--test/3rdparty/extras-0.0.3/extras/__init__.py105
-rw-r--r--test/3rdparty/extras-0.0.3/extras/tests/__init__.py17
-rw-r--r--test/3rdparty/extras-0.0.3/extras/tests/test_extras.py188
-rw-r--r--test/3rdparty/extras-0.0.3/setup.cfg10
-rwxr-xr-xtest/3rdparty/extras-0.0.3/setup.py43
16 files changed, 697 insertions, 0 deletions
diff --git a/test/3rdparty/extras-0.0.3/.gitignore b/test/3rdparty/extras-0.0.3/.gitignore
new file mode 100644
index 00000000000..cfc114cbe95
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/.gitignore
@@ -0,0 +1,35 @@
+*.py[co]
+
+# Packages
+*.egg
+*.egg-info
+dist
+build
+eggs
+parts
+bin
+var
+sdist
+develop-eggs
+.installed.cfg
+MANIFEST
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
+
+# editors
+*.swp
+*~
+
+# Testrepository
+.testrepository
diff --git a/test/3rdparty/extras-0.0.3/LICENSE b/test/3rdparty/extras-0.0.3/LICENSE
new file mode 100644
index 00000000000..4dfca452e1a
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2010-2012 the extras authors.
+
+The extras authors are:
+ * Jonathan Lange
+ * Martin Pool
+ * Robert Collins
+
+and are collectively referred to as "extras developers".
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/test/3rdparty/extras-0.0.3/MANIFEST.in b/test/3rdparty/extras-0.0.3/MANIFEST.in
new file mode 100644
index 00000000000..da2696e2430
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/MANIFEST.in
@@ -0,0 +1,6 @@
+include LICENSE
+include Makefile
+include MANIFEST.in
+include NEWS
+include README.rst
+include .gitignore
diff --git a/test/3rdparty/extras-0.0.3/Makefile b/test/3rdparty/extras-0.0.3/Makefile
new file mode 100644
index 00000000000..270e8d11546
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/Makefile
@@ -0,0 +1,30 @@
+# See README.rst for copyright and licensing details.
+
+PYTHON=python
+SOURCES=$(shell find extras -name "*.py")
+
+check:
+ PYTHONPATH=$(PWD) $(PYTHON) -m testtools.run extras.tests.test_suite
+
+TAGS: ${SOURCES}
+ ctags -e -R extras/
+
+tags: ${SOURCES}
+ ctags -R extras/
+
+clean:
+ rm -f TAGS tags
+ find extras -name "*.pyc" -exec rm '{}' \;
+
+### Documentation ###
+
+apidocs:
+ # pydoctor emits deprecation warnings under Ubuntu 10.10 LTS
+ PYTHONWARNINGS='ignore::DeprecationWarning' \
+ pydoctor --make-html --add-package extras \
+ --docformat=restructuredtext --project-name=extras \
+ --project-url=https://launchpad.net/extras
+
+
+.PHONY: apidocs
+.PHONY: check clean
diff --git a/test/3rdparty/extras-0.0.3/NEWS b/test/3rdparty/extras-0.0.3/NEWS
new file mode 100644
index 00000000000..60713b8efa6
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/NEWS
@@ -0,0 +1,27 @@
+extras NEWS
++++++++++++
+
+Changes and improvements to extras_, grouped by release.
+
+NEXT
+~~~~
+
+0.0.3
+~~~~~
+
+* Extras setup.py would break on older testtools releases, which could break
+ installs of newer testtools due to extras then failing to install.
+ (Robert Collins)
+
+0.0.2
+~~~~~
+
+* Fix Makefile to not have cruft leftover from testtools.
+
+0.0.1
+~~~~~
+
+* Initial extraction from testtools.
+
+
+.. _extras: http://pypi.python.org/pypi/extras
diff --git a/test/3rdparty/extras-0.0.3/PKG-INFO b/test/3rdparty/extras-0.0.3/PKG-INFO
new file mode 100644
index 00000000000..645b7c7e619
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/PKG-INFO
@@ -0,0 +1,68 @@
+Metadata-Version: 1.1
+Name: extras
+Version: 0.0.3
+Summary: Useful extra bits for Python - things that shold be in the standard library
+Home-page: https://github.com/testing-cabal/extras
+Author: Testing cabal
+Author-email: testtools-dev@lists.launchpad.net
+License: UNKNOWN
+Description: ======
+ extras
+ ======
+
+ extras is a set of extensions to the Python standard library, originally
+ written to make the code within testtools cleaner, but now split out for
+ general use outside of a testing context.
+
+
+ Documentation
+ -------------
+
+ pydoc extras is your friend. extras currently contains the following functions:
+
+ * try_import
+
+ * try_imports
+
+ * safe_hasattr
+
+ Which do what their name suggests.
+
+
+ Licensing
+ ---------
+
+ This project is distributed under the MIT license and copyright is owned by
+ the extras authors. See LICENSE for details.
+
+
+ Required Dependencies
+ ---------------------
+
+ * Python 2.6+ or 3.0+
+
+
+ Bug reports and patches
+ -----------------------
+
+ Please report bugs using github issues at <https://github.com/testing-cabal/extras>.
+ Patches can also be submitted via github. You can mail the authors directly
+ via the mailing list testtools-dev@lists.launchpad.net. (Note that Launchpad
+ discards email from unknown addresses - be sure to sign up for a Launchpad
+ account before mailing the list, or your mail will be silently discarded).
+
+
+ History
+ -------
+
+ extras used to be testtools.helpers, and was factored out when folk wanted to
+ use it separately.
+
+
+ Thanks
+ ------
+
+ * Martin Pool
+
+Platform: UNKNOWN
+Classifier: License :: OSI Approved :: MIT License
diff --git a/test/3rdparty/extras-0.0.3/README.rst b/test/3rdparty/extras-0.0.3/README.rst
new file mode 100644
index 00000000000..7d3f10ba93c
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/README.rst
@@ -0,0 +1,57 @@
+======
+extras
+======
+
+extras is a set of extensions to the Python standard library, originally
+written to make the code within testtools cleaner, but now split out for
+general use outside of a testing context.
+
+
+Documentation
+-------------
+
+pydoc extras is your friend. extras currently contains the following functions:
+
+* try_import
+
+* try_imports
+
+* safe_hasattr
+
+Which do what their name suggests.
+
+
+Licensing
+---------
+
+This project is distributed under the MIT license and copyright is owned by
+the extras authors. See LICENSE for details.
+
+
+Required Dependencies
+---------------------
+
+ * Python 2.6+ or 3.0+
+
+
+Bug reports and patches
+-----------------------
+
+Please report bugs using github issues at <https://github.com/testing-cabal/extras>.
+Patches can also be submitted via github. You can mail the authors directly
+via the mailing list testtools-dev@lists.launchpad.net. (Note that Launchpad
+discards email from unknown addresses - be sure to sign up for a Launchpad
+account before mailing the list, or your mail will be silently discarded).
+
+
+History
+-------
+
+extras used to be testtools.helpers, and was factored out when folk wanted to
+use it separately.
+
+
+Thanks
+------
+
+ * Martin Pool
diff --git a/test/3rdparty/extras-0.0.3/extras.egg-info/PKG-INFO b/test/3rdparty/extras-0.0.3/extras.egg-info/PKG-INFO
new file mode 100644
index 00000000000..645b7c7e619
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/extras.egg-info/PKG-INFO
@@ -0,0 +1,68 @@
+Metadata-Version: 1.1
+Name: extras
+Version: 0.0.3
+Summary: Useful extra bits for Python - things that shold be in the standard library
+Home-page: https://github.com/testing-cabal/extras
+Author: Testing cabal
+Author-email: testtools-dev@lists.launchpad.net
+License: UNKNOWN
+Description: ======
+ extras
+ ======
+
+ extras is a set of extensions to the Python standard library, originally
+ written to make the code within testtools cleaner, but now split out for
+ general use outside of a testing context.
+
+
+ Documentation
+ -------------
+
+ pydoc extras is your friend. extras currently contains the following functions:
+
+ * try_import
+
+ * try_imports
+
+ * safe_hasattr
+
+ Which do what their name suggests.
+
+
+ Licensing
+ ---------
+
+ This project is distributed under the MIT license and copyright is owned by
+ the extras authors. See LICENSE for details.
+
+
+ Required Dependencies
+ ---------------------
+
+ * Python 2.6+ or 3.0+
+
+
+ Bug reports and patches
+ -----------------------
+
+ Please report bugs using github issues at <https://github.com/testing-cabal/extras>.
+ Patches can also be submitted via github. You can mail the authors directly
+ via the mailing list testtools-dev@lists.launchpad.net. (Note that Launchpad
+ discards email from unknown addresses - be sure to sign up for a Launchpad
+ account before mailing the list, or your mail will be silently discarded).
+
+
+ History
+ -------
+
+ extras used to be testtools.helpers, and was factored out when folk wanted to
+ use it separately.
+
+
+ Thanks
+ ------
+
+ * Martin Pool
+
+Platform: UNKNOWN
+Classifier: License :: OSI Approved :: MIT License
diff --git a/test/3rdparty/extras-0.0.3/extras.egg-info/SOURCES.txt b/test/3rdparty/extras-0.0.3/extras.egg-info/SOURCES.txt
new file mode 100644
index 00000000000..7abc10f3073
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/extras.egg-info/SOURCES.txt
@@ -0,0 +1,15 @@
+.gitignore
+LICENSE
+MANIFEST.in
+Makefile
+NEWS
+README.rst
+setup.cfg
+setup.py
+extras/__init__.py
+extras.egg-info/PKG-INFO
+extras.egg-info/SOURCES.txt
+extras.egg-info/dependency_links.txt
+extras.egg-info/top_level.txt
+extras/tests/__init__.py
+extras/tests/test_extras.py \ No newline at end of file
diff --git a/test/3rdparty/extras-0.0.3/extras.egg-info/dependency_links.txt b/test/3rdparty/extras-0.0.3/extras.egg-info/dependency_links.txt
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/extras.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/test/3rdparty/extras-0.0.3/extras.egg-info/top_level.txt b/test/3rdparty/extras-0.0.3/extras.egg-info/top_level.txt
new file mode 100644
index 00000000000..8c35a2295a8
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/extras.egg-info/top_level.txt
@@ -0,0 +1 @@
+extras
diff --git a/test/3rdparty/extras-0.0.3/extras/__init__.py b/test/3rdparty/extras-0.0.3/extras/__init__.py
new file mode 100644
index 00000000000..2d34b5258de
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/extras/__init__.py
@@ -0,0 +1,105 @@
+# Copyright (c) 2010-2012 extras developers. See LICENSE for details.
+
+"""Extensions to the Python standard library."""
+
+import sys
+
+__all__ = [
+ 'safe_hasattr',
+ 'try_import',
+ 'try_imports',
+ ]
+
+# same format as sys.version_info: "A tuple containing the five components of
+# the version number: major, minor, micro, releaselevel, and serial. All
+# values except releaselevel are integers; the release level is 'alpha',
+# 'beta', 'candidate', or 'final'. The version_info value corresponding to the
+# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
+# releaselevel of 'dev' for unreleased under-development code.
+#
+# If the releaselevel is 'alpha' then the major/minor/micro components are not
+# established at this point, and setup.py will use a version of next-$(revno).
+# If the releaselevel is 'final', then the tarball will be major.minor.micro.
+# Otherwise it is major.minor.micro~$(revno).
+
+__version__ = (0, 0, 3, 'final', 0)
+
+
+def try_import(name, alternative=None, error_callback=None):
+ """Attempt to import ``name``. If it fails, return ``alternative``.
+
+ When supporting multiple versions of Python or optional dependencies, it
+ is useful to be able to try to import a module.
+
+ :param name: The name of the object to import, e.g. ``os.path`` or
+ ``os.path.join``.
+ :param alternative: The value to return if no module can be imported.
+ Defaults to None.
+ :param error_callback: If non-None, a callable that is passed the ImportError
+ when the module cannot be loaded.
+ """
+ module_segments = name.split('.')
+ last_error = None
+ while module_segments:
+ module_name = '.'.join(module_segments)
+ try:
+ module = __import__(module_name)
+ except ImportError:
+ last_error = sys.exc_info()[1]
+ module_segments.pop()
+ continue
+ else:
+ break
+ else:
+ if last_error is not None and error_callback is not None:
+ error_callback(last_error)
+ return alternative
+ nonexistent = object()
+ for segment in name.split('.')[1:]:
+ module = getattr(module, segment, nonexistent)
+ if module is nonexistent:
+ if last_error is not None and error_callback is not None:
+ error_callback(last_error)
+ return alternative
+ return module
+
+
+_RAISE_EXCEPTION = object()
+def try_imports(module_names, alternative=_RAISE_EXCEPTION, error_callback=None):
+ """Attempt to import modules.
+
+ Tries to import the first module in ``module_names``. If it can be
+ imported, we return it. If not, we go on to the second module and try
+ that. The process continues until we run out of modules to try. If none
+ of the modules can be imported, either raise an exception or return the
+ provided ``alternative`` value.
+
+ :param module_names: A sequence of module names to try to import.
+ :param alternative: The value to return if no module can be imported.
+ If unspecified, we raise an ImportError.
+ :param error_callback: If None, called with the ImportError for *each*
+ module that fails to load.
+ :raises ImportError: If none of the modules can be imported and no
+ alternative value was specified.
+ """
+ module_names = list(module_names)
+ for module_name in module_names:
+ module = try_import(module_name, error_callback=error_callback)
+ if module:
+ return module
+ if alternative is _RAISE_EXCEPTION:
+ raise ImportError(
+ "Could not import any of: %s" % ', '.join(module_names))
+ return alternative
+
+
+def safe_hasattr(obj, attr, _marker=object()):
+ """Does 'obj' have an attribute 'attr'?
+
+ Use this rather than built-in hasattr, as the built-in swallows exceptions
+ in some versions of Python and behaves unpredictably with respect to
+ properties.
+ """
+ return getattr(obj, attr, _marker) is not _marker
+
+
diff --git a/test/3rdparty/extras-0.0.3/extras/tests/__init__.py b/test/3rdparty/extras-0.0.3/extras/tests/__init__.py
new file mode 100644
index 00000000000..e0d7d4a34d6
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/extras/tests/__init__.py
@@ -0,0 +1,17 @@
+# Copyright (c) 2010-2012 extras developers. See LICENSE for details.
+
+"""Tests for extras."""
+
+from unittest import TestSuite, TestLoader
+
+
+def test_suite():
+ from extras.tests import (
+ test_extras,
+ )
+ modules = [
+ test_extras,
+ ]
+ loader = TestLoader()
+ suites = map(loader.loadTestsFromModule, modules)
+ return TestSuite(suites)
diff --git a/test/3rdparty/extras-0.0.3/extras/tests/test_extras.py b/test/3rdparty/extras-0.0.3/extras/tests/test_extras.py
new file mode 100644
index 00000000000..be1ed1c69f6
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/extras/tests/test_extras.py
@@ -0,0 +1,188 @@
+# Copyright (c) 2010-2012 extras developers. See LICENSE for details.
+
+from testtools import TestCase
+from testtools.matchers import (
+ Equals,
+ Is,
+ Not,
+ )
+
+from extras import (
+ safe_hasattr,
+ try_import,
+ try_imports,
+ )
+
+def check_error_callback(test, function, arg, expected_error_count,
+ expect_result):
+ """General test template for error_callback argument.
+
+ :param test: Test case instance.
+ :param function: Either try_import or try_imports.
+ :param arg: Name or names to import.
+ :param expected_error_count: Expected number of calls to the callback.
+ :param expect_result: Boolean for whether a module should
+ ultimately be returned or not.
+ """
+ cb_calls = []
+ def cb(e):
+ test.assertIsInstance(e, ImportError)
+ cb_calls.append(e)
+ try:
+ result = function(arg, error_callback=cb)
+ except ImportError:
+ test.assertFalse(expect_result)
+ else:
+ if expect_result:
+ test.assertThat(result, Not(Is(None)))
+ else:
+ test.assertThat(result, Is(None))
+ test.assertEquals(len(cb_calls), expected_error_count)
+
+
+class TestSafeHasattr(TestCase):
+
+ def test_attribute_not_there(self):
+ class Foo(object):
+ pass
+ self.assertEqual(False, safe_hasattr(Foo(), 'anything'))
+
+ def test_attribute_there(self):
+ class Foo(object):
+ pass
+ foo = Foo()
+ foo.attribute = None
+ self.assertEqual(True, safe_hasattr(foo, 'attribute'))
+
+ def test_property_there(self):
+ class Foo(object):
+ @property
+ def attribute(self):
+ return None
+ foo = Foo()
+ self.assertEqual(True, safe_hasattr(foo, 'attribute'))
+
+ def test_property_raises(self):
+ class Foo(object):
+ @property
+ def attribute(self):
+ 1/0
+ foo = Foo()
+ self.assertRaises(ZeroDivisionError, safe_hasattr, foo, 'attribute')
+
+
+class TestTryImport(TestCase):
+
+ def test_doesnt_exist(self):
+ # try_import('thing', foo) returns foo if 'thing' doesn't exist.
+ marker = object()
+ result = try_import('doesntexist', marker)
+ self.assertThat(result, Is(marker))
+
+ def test_None_is_default_alternative(self):
+ # try_import('thing') returns None if 'thing' doesn't exist.
+ result = try_import('doesntexist')
+ self.assertThat(result, Is(None))
+
+ def test_existing_module(self):
+ # try_import('thing', foo) imports 'thing' and returns it if it's a
+ # module that exists.
+ result = try_import('os', object())
+ import os
+ self.assertThat(result, Is(os))
+
+ def test_existing_submodule(self):
+ # try_import('thing.another', foo) imports 'thing' and returns it if
+ # it's a module that exists.
+ result = try_import('os.path', object())
+ import os
+ self.assertThat(result, Is(os.path))
+
+ def test_nonexistent_submodule(self):
+ # try_import('thing.another', foo) imports 'thing' and returns foo if
+ # 'another' doesn't exist.
+ marker = object()
+ result = try_import('os.doesntexist', marker)
+ self.assertThat(result, Is(marker))
+
+ def test_object_from_module(self):
+ # try_import('thing.object') imports 'thing' and returns
+ # 'thing.object' if 'thing' is a module and 'object' is not.
+ result = try_import('os.path.join')
+ import os
+ self.assertThat(result, Is(os.path.join))
+
+ def test_error_callback(self):
+ # the error callback is called on failures.
+ check_error_callback(self, try_import, 'doesntexist', 1, False)
+
+ def test_error_callback_missing_module_member(self):
+ # the error callback is called on failures to find an object
+ # inside an existing module.
+ check_error_callback(self, try_import, 'os.nonexistent', 1, False)
+
+ def test_error_callback_not_on_success(self):
+ # the error callback is not called on success.
+ check_error_callback(self, try_import, 'os.path', 0, True)
+
+
+class TestTryImports(TestCase):
+
+ def test_doesnt_exist(self):
+ # try_imports('thing', foo) returns foo if 'thing' doesn't exist.
+ marker = object()
+ result = try_imports(['doesntexist'], marker)
+ self.assertThat(result, Is(marker))
+
+ def test_fallback(self):
+ result = try_imports(['doesntexist', 'os'])
+ import os
+ self.assertThat(result, Is(os))
+
+ def test_None_is_default_alternative(self):
+ # try_imports('thing') returns None if 'thing' doesn't exist.
+ e = self.assertRaises(
+ ImportError, try_imports, ['doesntexist', 'noreally'])
+ self.assertThat(
+ str(e),
+ Equals("Could not import any of: doesntexist, noreally"))
+
+ def test_existing_module(self):
+ # try_imports('thing', foo) imports 'thing' and returns it if it's a
+ # module that exists.
+ result = try_imports(['os'], object())
+ import os
+ self.assertThat(result, Is(os))
+
+ def test_existing_submodule(self):
+ # try_imports('thing.another', foo) imports 'thing' and returns it if
+ # it's a module that exists.
+ result = try_imports(['os.path'], object())
+ import os
+ self.assertThat(result, Is(os.path))
+
+ def test_nonexistent_submodule(self):
+ # try_imports('thing.another', foo) imports 'thing' and returns foo if
+ # 'another' doesn't exist.
+ marker = object()
+ result = try_imports(['os.doesntexist'], marker)
+ self.assertThat(result, Is(marker))
+
+ def test_fallback_submodule(self):
+ result = try_imports(['os.doesntexist', 'os.path'])
+ import os
+ self.assertThat(result, Is(os.path))
+
+ def test_error_callback(self):
+ # One error for every class that doesn't exist.
+ check_error_callback(self, try_imports,
+ ['os.doesntexist', 'os.notthiseither'],
+ 2, False)
+ check_error_callback(self, try_imports,
+ ['os.doesntexist', 'os.notthiseither', 'os'],
+ 2, True)
+ check_error_callback(self, try_imports,
+ ['os.path'],
+ 0, True)
+
+
diff --git a/test/3rdparty/extras-0.0.3/setup.cfg b/test/3rdparty/extras-0.0.3/setup.cfg
new file mode 100644
index 00000000000..92ee5499429
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/setup.cfg
@@ -0,0 +1,10 @@
+[test]
+test_module = extras.tests
+buffer = 1
+catch = 1
+
+[egg_info]
+tag_build =
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/test/3rdparty/extras-0.0.3/setup.py b/test/3rdparty/extras-0.0.3/setup.py
new file mode 100755
index 00000000000..c384a765801
--- /dev/null
+++ b/test/3rdparty/extras-0.0.3/setup.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+"""Distutils installer for extras."""
+
+from setuptools import setup
+import os.path
+
+import extras
+testtools_cmd = extras.try_import('testtools.TestCommand')
+
+
+def get_version():
+ """Return the version of extras that we are building."""
+ version = '.'.join(
+ str(component) for component in extras.__version__[0:3])
+ return version
+
+
+def get_long_description():
+ readme_path = os.path.join(
+ os.path.dirname(__file__), 'README.rst')
+ return open(readme_path).read()
+
+
+cmdclass = {}
+
+if testtools_cmd is not None:
+ cmdclass['test'] = testtools_cmd
+
+
+setup(name='extras',
+ author='Testing cabal',
+ author_email='testtools-dev@lists.launchpad.net',
+ url='https://github.com/testing-cabal/extras',
+ description=('Useful extra bits for Python - things that shold be '
+ 'in the standard library'),
+ long_description=get_long_description(),
+ version=get_version(),
+ classifiers=["License :: OSI Approved :: MIT License"],
+ packages=[
+ 'extras',
+ 'extras.tests',
+ ],
+ cmdclass=cmdclass)