summaryrefslogtreecommitdiff
path: root/passlib/tests/backports.py
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2015-01-10 18:52:34 -0500
committerEli Collins <elic@assurancetechnologies.com>2015-01-10 18:52:34 -0500
commitcf8fce4325d259490ada92caa624cb1a1c8e21b5 (patch)
treef52587a6308cf389dbadf56492dfbeb592c9ee47 /passlib/tests/backports.py
parent55062360b26ace8d2521fe67a518ebf434f7847f (diff)
downloadpasslib-cf8fce4325d259490ada92caa624cb1a1c8e21b5.tar.gz
removed a LOT of compatibility shims -- dropped python 2.5, 3.0, and 3.1 support;
as well as PyPy 1.x and Jython 2.5. shims removed ------------- * b() shim replaced with b'' (py25) * 'bytes' alias no longer needed (py25) * callable() shim no longer needed (py30,31) * PY_MIN_32 flag replaced with PY3 flag (py30,31) * removed 'abc' module stub used by passlib.ifc (py25) * removed chain_from_iterable() backport (py25) * tests: removed catch_warnings() backport, replaced refs with real warnings.catch_warnings() (py25) * tests: removed unittest2 backports (py25, py30, py31) -- now throw hard error if unittest2 not present under py26 (the only release remaining which lacks the unittest2 features) * removed SUPPORTS_DIR_METHOD conditional (py25, pypy 1.x) * some other minor workarounds other ----- * added check in passlib.compat which now throws error telling user version isn't supported (to prevent spurious errors later)
Diffstat (limited to 'passlib/tests/backports.py')
-rw-r--r--passlib/tests/backports.py295
1 files changed, 15 insertions, 280 deletions
diff --git a/passlib/tests/backports.py b/passlib/tests/backports.py
index 1868259..347eeb7 100644
--- a/passlib/tests/backports.py
+++ b/passlib/tests/backports.py
@@ -15,7 +15,6 @@ from passlib.utils.compat import base_string_types
__all__ = [
"TestCase",
"skip", "skipIf", "skipUnless"
- "catch_warnings",
]
#=============================================================================
@@ -23,307 +22,43 @@ __all__ = [
#=============================================================================
try:
import unittest2 as unittest
- ut_version = 2
except ImportError:
+ if sys.version_info < (2,7):
+ raise ImportError("Passlib's tests require 'unittest2' under Python 2.6 (as of Passlib 1.7)")
+ # python 2.7 and python 3.2 both have unittest2 features (at least, the ones we use)
import unittest
- if sys.version_info < (2,7) or (3,0) <= sys.version_info < (3,2):
- # older versions of python will need to install the unittest2
- # backport (named unittest2_3k for 3.0/3.1)
- ##warn("please install unittest2 for python %d.%d, it will be required "
- ## "as of passlib 1.x" % sys.version_info[:2])
- ut_version = 1
- else:
- ut_version = 2
#=============================================================================
-# backport SkipTest support using nose
+# unittest aliases
#=============================================================================
-if ut_version < 2:
- # used to provide replacement SkipTest() error
- from nose.plugins.skip import SkipTest
-
- # hack up something to simulate skip() decorator
- import functools
- def skip(reason):
- def decorator(test_item):
- if isinstance(test_item, type) and issubclass(test_item, unittest.TestCase):
- class skip_wrapper(test_item):
- def setUp(self):
- raise SkipTest(reason)
- else:
- @functools.wraps(test_item)
- def skip_wrapper(*args, **kwargs):
- raise SkipTest(reason)
- return skip_wrapper
- return decorator
-
- def skipIf(condition, reason):
- if condition:
- return skip(reason)
- else:
- return lambda item: item
-
- def skipUnless(condition, reason):
- if condition:
- return lambda item: item
- else:
- return skip(reason)
-
-else:
- skip = unittest.skip
- skipIf = unittest.skipIf
- skipUnless = unittest.skipUnless
+skip = unittest.skip
+skipIf = unittest.skipIf
+skipUnless = unittest.skipUnless
#=============================================================================
# custom test harness
#=============================================================================
class TestCase(unittest.TestCase):
"""backports a number of unittest2 features in TestCase"""
+
#===================================================================
- # backport some methods from unittest2
+ # backport some unittest2 names
#===================================================================
- if ut_version < 2:
-
- #----------------------------------------------------------------
- # simplistic backport of addCleanup() framework
- #----------------------------------------------------------------
- _cleanups = None
-
- def addCleanup(self, function, *args, **kwds):
- queue = self._cleanups
- if queue is None:
- queue = self._cleanups = []
- queue.append((function, args, kwds))
-
- def doCleanups(self):
- queue = self._cleanups
- while queue:
- func, args, kwds = queue.pop()
- func(*args, **kwds)
-
- def tearDown(self):
- self.doCleanups()
- unittest.TestCase.tearDown(self)
-
- #----------------------------------------------------------------
- # backport skipTest (requires nose to work)
- #----------------------------------------------------------------
- def skipTest(self, reason):
- raise SkipTest(reason)
-
- #----------------------------------------------------------------
- # backport various assert tests added in unittest2
- #----------------------------------------------------------------
- def assertIs(self, real, correct, msg=None):
- if real is not correct:
- std = "got %r, expected would be %r" % (real, correct)
- msg = self._formatMessage(msg, std)
- raise self.failureException(msg)
-
- def assertIsNot(self, real, correct, msg=None):
- if real is correct:
- std = "got %r, expected would not be %r" % (real, correct)
- msg = self._formatMessage(msg, std)
- raise self.failureException(msg)
-
- def assertIsInstance(self, obj, klass, msg=None):
- if not isinstance(obj, klass):
- std = "got %r, expected instance of %r" % (obj, klass)
- msg = self._formatMessage(msg, std)
- raise self.failureException(msg)
-
- def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
- """Fail if the two objects are unequal as determined by their
- difference rounded to the given number of decimal places
- (default 7) and comparing to zero, or by comparing that the
- between the two objects is more than the given delta.
-
- Note that decimal places (from zero) are usually not the same
- as significant digits (measured from the most signficant digit).
-
- If the two objects compare equal then they will automatically
- compare almost equal.
- """
- if first == second:
- # shortcut
- return
- if delta is not None and places is not None:
- raise TypeError("specify delta or places not both")
-
- if delta is not None:
- if abs(first - second) <= delta:
- return
-
- standardMsg = '%s != %s within %s delta' % (repr(first),
- repr(second),
- repr(delta))
- else:
- if places is None:
- places = 7
-
- if round(abs(second-first), places) == 0:
- return
-
- standardMsg = '%s != %s within %r places' % (repr(first),
- repr(second),
- places)
- msg = self._formatMessage(msg, standardMsg)
- raise self.failureException(msg)
-
- def assertLess(self, left, right, msg=None):
- if left >= right:
- std = "%r not less than %r" % (left, right)
- raise self.failureException(self._formatMessage(msg, std))
-
- def assertGreater(self, left, right, msg=None):
- if left <= right:
- std = "%r not greater than %r" % (left, right)
- raise self.failureException(self._formatMessage(msg, std))
-
- def assertGreaterEqual(self, left, right, msg=None):
- if left < right:
- std = "%r less than %r" % (left, right)
- raise self.failureException(self._formatMessage(msg, std))
-
- def assertIn(self, elem, container, msg=None):
- if elem not in container:
- std = "%r not found in %r" % (elem, container)
- raise self.failureException(self._formatMessage(msg, std))
-
- def assertNotIn(self, elem, container, msg=None):
- if elem in container:
- std = "%r unexpectedly in %r" % (elem, container)
- raise self.failureException(self._formatMessage(msg, std))
-
- #----------------------------------------------------------------
- # override some unittest1 methods to support _formatMessage
- #----------------------------------------------------------------
- def assertEqual(self, real, correct, msg=None):
- if real != correct:
- std = "got %r, expected would equal %r" % (real, correct)
- msg = self._formatMessage(msg, std)
- raise self.failureException(msg)
-
- def assertNotEqual(self, real, correct, msg=None):
- if real == correct:
- std = "got %r, expected would not equal %r" % (real, correct)
- msg = self._formatMessage(msg, std)
- raise self.failureException(msg)
#---------------------------------------------------------------
- # backport assertRegex() alias from 3.2 to 2.7/3.1
+ # backport assertRegex() alias from 3.2 to 2.7
+ # was present in 2.7 under an alternate name
#---------------------------------------------------------------
if not hasattr(unittest.TestCase, "assertRegex"):
- if hasattr(unittest.TestCase, "assertRegexpMatches"):
- # was present in 2.7/3.1 under name assertRegexpMatches
- assertRegex = unittest.TestCase.assertRegexpMatches
- else:
- # 3.0 and <= 2.6 didn't have this method at all
- def assertRegex(self, text, expected_regex, msg=None):
- """Fail the test unless the text matches the regular expression."""
- if isinstance(expected_regex, base_string_types):
- assert expected_regex, "expected_regex must not be empty."
- expected_regex = re.compile(expected_regex)
- if not expected_regex.search(text):
- msg = msg or "Regex didn't match: "
- std = '%r not found in %r' % (expected_regex.pattern, text)
- raise self.failureException(self._formatMessage(msg, std))
+ assertRegex = unittest.TestCase.assertRegexpMatches
+
+ if not hasattr(unittest.TestCase, "assertRaisesRegex"):
+ assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
#===================================================================
# eoc
#===================================================================
#=============================================================================
-# backport catch_warnings
-#=============================================================================
-try:
- from warnings import catch_warnings
-except ImportError:
- # catch_warnings wasn't added until py26.
- # this adds backported copy from py26's stdlib
- # so we can use it under py25.
-
- class WarningMessage(object):
-
- """Holds the result of a single showwarning() call."""
-
- _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
- "line")
-
- def __init__(self, message, category, filename, lineno, file=None,
- line=None):
- local_values = locals()
- for attr in self._WARNING_DETAILS:
- setattr(self, attr, local_values[attr])
- self._category_name = category.__name__ if category else None
-
- def __str__(self):
- return ("{message : %r, category : %r, filename : %r, lineno : %s, "
- "line : %r}" % (self.message, self._category_name,
- self.filename, self.lineno, self.line))
-
-
- class catch_warnings(object):
-
- """A context manager that copies and restores the warnings filter upon
- exiting the context.
-
- The 'record' argument specifies whether warnings should be captured by a
- custom implementation of warnings.showwarning() and be appended to a list
- returned by the context manager. Otherwise None is returned by the context
- manager. The objects appended to the list are arguments whose attributes
- mirror the arguments to showwarning().
-
- The 'module' argument is to specify an alternative module to the module
- named 'warnings' and imported under that name. This argument is only useful
- when testing the warnings module itself.
-
- """
-
- def __init__(self, record=False, module=None):
- """Specify whether to record warnings and if an alternative module
- should be used other than sys.modules['warnings'].
-
- For compatibility with Python 3.0, please consider all arguments to be
- keyword-only.
-
- """
- self._record = record
- self._module = sys.modules['warnings'] if module is None else module
- self._entered = False
-
- def __repr__(self):
- args = []
- if self._record:
- args.append("record=True")
- if self._module is not sys.modules['warnings']:
- args.append("module=%r" % self._module)
- name = type(self).__name__
- return "%s(%s)" % (name, ", ".join(args))
-
- def __enter__(self):
- if self._entered:
- raise RuntimeError("Cannot enter %r twice" % self)
- self._entered = True
- self._filters = self._module.filters
- self._module.filters = self._filters[:]
- self._showwarning = self._module.showwarning
- if self._record:
- log = []
- def showwarning(*args, **kwargs):
-# self._showwarning(*args, **kwargs)
- log.append(WarningMessage(*args, **kwargs))
- self._module.showwarning = showwarning
- return log
- else:
- return None
-
- def __exit__(self, *exc_info):
- if not self._entered:
- raise RuntimeError("Cannot exit %r without entering first" % self)
- self._module.filters = self._filters
- self._module.showwarning = self._showwarning
-
-#=============================================================================
# eof
#=============================================================================