| import sys
|
| import unittest
|
| try:
|
| from StringIO import StringIO
|
| except ImportError:
|
| from io import StringIO
|
|
|
| from Cython.Utils import (
|
| _CACHE_NAME_PATTERN, _build_cache_name, _find_cache_attributes,
|
| build_hex_version, cached_method, clear_method_caches, try_finally_contextmanager,
|
| print_version, normalise_float_repr,
|
| )
|
|
|
| METHOD_NAME = "cached_next"
|
| CACHE_NAME = _build_cache_name(METHOD_NAME)
|
| NAMES = CACHE_NAME, METHOD_NAME
|
|
|
| class Cached(object):
|
| @cached_method
|
| def cached_next(self, x):
|
| return next(x)
|
|
|
|
|
| class TestCythonUtils(unittest.TestCase):
|
| def test_build_hex_version(self):
|
| self.assertEqual('0x001D00A1', build_hex_version('0.29a1'))
|
| self.assertEqual('0x001D03C4', build_hex_version('0.29.3rc4'))
|
| self.assertEqual('0x001D00F0', build_hex_version('0.29'))
|
| self.assertEqual('0x040000F0', build_hex_version('4.0'))
|
|
|
|
|
|
|
| def test_cache_method_name(self):
|
| method_name = "foo"
|
| cache_name = _build_cache_name(method_name)
|
| match = _CACHE_NAME_PATTERN.match(cache_name)
|
|
|
| self.assertIsNot(match, None)
|
| self.assertEqual(match.group(1), method_name)
|
|
|
| def test_requirements_for_Cached(self):
|
| obj = Cached()
|
|
|
| self.assertFalse(hasattr(obj, CACHE_NAME))
|
| self.assertTrue(hasattr(obj, METHOD_NAME))
|
| self.set_of_names_equal(obj, set())
|
|
|
| def set_of_names_equal(self, obj, value):
|
| self.assertEqual(set(_find_cache_attributes(obj)), value)
|
|
|
| def test_find_cache_attributes(self):
|
| obj = Cached()
|
| method_name = "bar"
|
| cache_name = _build_cache_name(method_name)
|
|
|
| setattr(obj, CACHE_NAME, {})
|
| setattr(obj, cache_name, {})
|
|
|
| self.assertFalse(hasattr(obj, method_name))
|
| self.set_of_names_equal(obj, {NAMES, (cache_name, method_name)})
|
|
|
| def test_cached_method(self):
|
| obj = Cached()
|
| value = iter(range(3))
|
| cache = {(value,): 0}
|
|
|
|
|
| self.assertEqual(obj.cached_next(value), 0)
|
| self.set_of_names_equal(obj, {NAMES})
|
| self.assertEqual(getattr(obj, CACHE_NAME), cache)
|
|
|
|
|
| self.assertEqual(obj.cached_next(value), 0)
|
| self.set_of_names_equal(obj, {NAMES})
|
| self.assertEqual(getattr(obj, CACHE_NAME), cache)
|
|
|
| def test_clear_method_caches(self):
|
| obj = Cached()
|
| value = iter(range(3))
|
| cache = {(value,): 1}
|
|
|
| obj.cached_next(value)
|
|
|
| clear_method_caches(obj)
|
| self.set_of_names_equal(obj, set())
|
|
|
| self.assertEqual(obj.cached_next(value), 1)
|
| self.set_of_names_equal(obj, {NAMES})
|
| self.assertEqual(getattr(obj, CACHE_NAME), cache)
|
|
|
| def test_clear_method_caches_with_missing_method(self):
|
| obj = Cached()
|
| method_name = "bar"
|
| cache_name = _build_cache_name(method_name)
|
| names = cache_name, method_name
|
|
|
| setattr(obj, cache_name, object())
|
|
|
| self.assertFalse(hasattr(obj, method_name))
|
| self.set_of_names_equal(obj, {names})
|
|
|
| clear_method_caches(obj)
|
| self.set_of_names_equal(obj, {names})
|
|
|
| def test_try_finally_contextmanager(self):
|
| states = []
|
| @try_finally_contextmanager
|
| def gen(*args, **kwargs):
|
| states.append("enter")
|
| yield (args, kwargs)
|
| states.append("exit")
|
|
|
| with gen(1, 2, 3, x=4) as call_args:
|
| assert states == ["enter"]
|
| self.assertEqual(call_args, ((1, 2, 3), {'x': 4}))
|
| assert states == ["enter", "exit"]
|
|
|
| class MyException(RuntimeError):
|
| pass
|
|
|
| del states[:]
|
| with self.assertRaises(MyException):
|
| with gen(1, 2, y=4) as call_args:
|
| assert states == ["enter"]
|
| self.assertEqual(call_args, ((1, 2), {'y': 4}))
|
| raise MyException("FAIL INSIDE")
|
| assert states == ["enter", "exit"]
|
|
|
| del states[:]
|
| with self.assertRaises(StopIteration):
|
| with gen(1, 2, y=4) as call_args:
|
| assert states == ["enter"]
|
| self.assertEqual(call_args, ((1, 2), {'y': 4}))
|
| raise StopIteration("STOP")
|
| assert states == ["enter", "exit"]
|
|
|
| def test_print_version(self):
|
| orig_stderr = sys.stderr
|
| orig_stdout = sys.stdout
|
| stderr = sys.stderr = StringIO()
|
| stdout = sys.stdout = StringIO()
|
| try:
|
| print_version()
|
| finally:
|
| sys.stdout = orig_stdout
|
| sys.stderr = orig_stderr
|
|
|
| stdout = stdout.getvalue()
|
| stderr = stderr.getvalue()
|
|
|
| from .. import __version__ as version
|
| self.assertIn(version, stdout)
|
| if stderr:
|
| self.assertIn(version, stderr)
|
|
|
| def test_print_version_stdouterr(self):
|
| orig_stderr = sys.stderr
|
| orig_stdout = sys.stdout
|
| stdout = sys.stdout = sys.stderr = StringIO()
|
| try:
|
| print_version()
|
| finally:
|
| sys.stdout = orig_stdout
|
| sys.stderr = orig_stderr
|
|
|
| stdout = stdout.getvalue()
|
|
|
| from .. import __version__ as version
|
| self.assertIn(version, stdout)
|
| self.assertEqual(stdout.count(version), 1)
|
|
|
| def test_normalise_float_repr(self):
|
| examples = [
|
| ('.0', '.0'),
|
| ('.000000', '.0'),
|
| ('.1', '.1'),
|
| ('1.', '1.'),
|
| ('1.0', '1.'),
|
| ('1.000000000000000000000', '1.'),
|
| ('00000000000000000000001.000000000000000000000', '1.'),
|
| ('12345.0025', '12345.0025'),
|
| ('1E5', '100000.'),
|
| ('.1E-5', '.000001'),
|
| ('1.1E-5', '.000011'),
|
| ('12.3E-5', '.000123'),
|
| ('.1E10', '1000000000.'),
|
| ('1.1E10', '11000000000.'),
|
| ('123.4E10', '1234000000000.'),
|
| ('123.456E0', '123.456'),
|
| ('123.456E-1', '12.3456'),
|
| ('123.456E-2', '1.23456'),
|
| ('123.456E1', '1234.56'),
|
| ('123.456E2', '12345.6'),
|
| ('2.1E80', '210000000000000000000000000000000000000000000000000000000000000000000000000000000.'),
|
| ]
|
|
|
| for float_str, norm_str in examples:
|
| self.assertEqual(float(float_str), float(norm_str))
|
|
|
| result = normalise_float_repr(float_str)
|
| self.assertEqual(float(float_str), float(result))
|
| self.assertEqual(
|
| result, norm_str,
|
| "normalise_float_repr(%r) == %r != %r (%.330f)" % (float_str, result, norm_str, float(float_str))
|
| )
|
|
|