diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 42e2cecaeb724e..a7f99f7d6caa18 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -19,7 +19,7 @@ from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod from test import support -from test.support import is_resource_enabled, ALWAYS_EQ, LARGEST, SMALLEST +from test.support import is_resource_enabled, ALWAYS_EQ, LARGEST, SMALLEST, FakeInt import datetime as datetime_module from datetime import MINYEAR, MAXYEAR @@ -5076,15 +5076,9 @@ def test_extra_attributes(self): x.abc = 1 def test_check_arg_types(self): - class Number: - def __init__(self, value): - self.value = value - def __int__(self): - return self.value - for xx in [decimal.Decimal(10), decimal.Decimal('10.9'), - Number(10)]: + FakeInt(10)]: with self.assertWarns(DeprecationWarning): self.assertEqual(datetime(10, 10, 10, 10, 10, 10, 10), datetime(xx, xx, xx, xx, xx, xx, xx)) @@ -5093,7 +5087,7 @@ def __int__(self): r'\(got type str\)$'): datetime(10, 10, '10') - f10 = Number(10.9) + f10 = FakeInt(10.9) with self.assertRaisesRegex(TypeError, '^__int__ returned non-int ' r'\(type float\)$'): datetime(10, 10, f10) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 5b9aebbda79719..bb15cb56925b95 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -121,6 +121,7 @@ "run_with_tz", "PGO", "missing_compiler_executable", "fd_count", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", + "FakeIndex", "FakeInt", "FakeFloat", "FakeComplex", "FakePath", ] @@ -3189,22 +3190,37 @@ def with_pymalloc(): return _testcapi.WITH_PYMALLOC -class FakePath: - """Simple implementing of the path protocol. - """ - def __init__(self, path): - self.path = path +class Fake: + def __init__(self, value): + self.value = value def __repr__(self): - return f'' + return f'<{self.__class__.__name__} {self.value!r}>' - def __fspath__(self): - if (isinstance(self.path, BaseException) or - isinstance(self.path, type) and - issubclass(self.path, BaseException)): - raise self.path + def _return(self): + if (isinstance(self.value, BaseException) or + isinstance(self.value, type) and + issubclass(self.value, BaseException)): + raise self.value else: - return self.path + return self.value + +class FakeIndex(Fake): + __index__ = Fake._return + +class FakeInt(Fake): + __int__ = Fake._return + +class FakeFloat(Fake): + __float__ = Fake._return + +class FakeComplex(Fake): + __complex__ = Fake._return + +class FakePath(Fake): + """Simple implementing of the path protocol. + """ + __fspath__ = Fake._return class _ALWAYS_EQ: diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index d440bcf7e0faa1..b1e53f7b75e17f 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -16,6 +16,7 @@ import contextlib import unittest from test import support +from test.support import FakeIndex, FakeInt from itertools import permutations, product from random import randrange, sample, choice import warnings @@ -2510,22 +2511,9 @@ def test_memoryview_sizeof(self): check(memoryview(a), vsize(base_struct + 3 * per_dim)) def test_memoryview_struct_module(self): - - class INT(object): - def __init__(self, val): - self.val = val - def __int__(self): - return self.val - - class IDX(object): - def __init__(self, val): - self.val = val - def __index__(self): - return self.val - def f(): return 7 - values = [INT(9), IDX(9), + values = [FakeInt(9), FakeIndex(9), 2.2+3j, Decimal("-21.1"), 12.2, Fraction(5, 2), [1,2,3], {4,5,6}, {7:8}, (), (9,), True, False, None, Ellipsis, diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 770e2c5592cc61..168d8fecf20c55 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -18,7 +18,7 @@ import test.support import test.string_tests import test.list_tests -from test.support import bigaddrspacetest, MAX_Py_ssize_t +from test.support import bigaddrspacetest, MAX_Py_ssize_t, FakeIndex from test.support.script_helper import assert_python_failure @@ -35,13 +35,6 @@ def check_bytes_warnings(func): return func -class Indexable: - def __init__(self, value=0): - self.value = value - def __index__(self): - return self.value - - class BaseBytesTest: def test_basics(self): @@ -133,11 +126,11 @@ def __index__(self): self.assertEqual(bytes(a), b'*' * 1000) # should not crash def test_from_index(self): - b = self.type2test([Indexable(), Indexable(1), Indexable(254), - Indexable(255)]) + b = self.type2test([FakeIndex(0), FakeIndex(1), FakeIndex(254), + FakeIndex(255)]) self.assertEqual(list(b), [0, 1, 254, 255]) - self.assertRaises(ValueError, self.type2test, [Indexable(-1)]) - self.assertRaises(ValueError, self.type2test, [Indexable(256)]) + self.assertRaises(ValueError, self.type2test, [FakeIndex(-1)]) + self.assertRaises(ValueError, self.type2test, [FakeIndex(256)]) def test_from_buffer(self): a = self.type2test(array.array('B', [1, 2, 3])) @@ -208,11 +201,8 @@ def test_constructor_overflow(self): def test_constructor_exceptions(self): # Issue #34974: bytes and bytearray constructors replace unexpected # exceptions. - class BadInt: - def __index__(self): - 1/0 - self.assertRaises(ZeroDivisionError, self.type2test, BadInt()) - self.assertRaises(ZeroDivisionError, self.type2test, [BadInt()]) + self.assertRaises(ZeroDivisionError, self.type2test, FakeIndex(ZeroDivisionError)) + self.assertRaises(ZeroDivisionError, self.type2test, [FakeIndex(ZeroDivisionError)]) class BadIterable: def __iter__(self): @@ -1267,7 +1257,7 @@ def test_setitem(self): self.assertEqual(b, bytearray([1, 100, 3])) b[-1] = 200 self.assertEqual(b, bytearray([1, 100, 200])) - b[0] = Indexable(10) + b[0] = FakeIndex(10) self.assertEqual(b, bytearray([10, 100, 200])) try: b[3] = 0 @@ -1285,7 +1275,7 @@ def test_setitem(self): except ValueError: pass try: - b[0] = Indexable(-1) + b[0] = FakeIndex(-1) self.fail("Didn't raise ValueError") except ValueError: pass @@ -1483,7 +1473,7 @@ def test_extend(self): self.assertRaises(ValueError, a.extend, [0, 1, 2, -1]) self.assertEqual(len(a), 0) a = bytearray(b'') - a.extend([Indexable(ord('a'))]) + a.extend([FakeIndex(ord('a'))]) self.assertEqual(a, b'a') def test_remove(self): @@ -1500,7 +1490,7 @@ def test_remove(self): b.remove(ord('h')) self.assertEqual(b, b'e') self.assertRaises(TypeError, lambda: b.remove(b'e')) - b.remove(Indexable(ord('e'))) + b.remove(FakeIndex(ord('e'))) self.assertEqual(b, b'') # test values outside of the ascii range: (0, 127) @@ -1533,7 +1523,7 @@ def test_append(self): self.assertEqual(len(b), 1) self.assertRaises(TypeError, lambda: b.append(b'o')) b = bytearray() - b.append(Indexable(ord('A'))) + b.append(FakeIndex(ord('A'))) self.assertEqual(b, b'A') def test_insert(self): @@ -1545,7 +1535,7 @@ def test_insert(self): self.assertEqual(b, b'mississippi') self.assertRaises(TypeError, lambda: b.insert(0, b'1')) b = bytearray() - b.insert(0, Indexable(ord('A'))) + b.insert(0, FakeIndex(ord('A'))) self.assertEqual(b, b'A') def test_copied(self): diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index 668f27c8a08272..097c31ef2ed56c 100644 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -1,4 +1,5 @@ from test.support import requires_IEEE_754, cpython_only +from test.support import FakeIndex, FakeInt, FakeFloat, FakeComplex from test.test_math import parse_testfile, test_file import test.test_math as test_math import unittest @@ -191,85 +192,34 @@ def test_user_object(self): # Now we introduce a variety of classes whose instances might # end up being passed to the cmath functions - # usual case: new-style class implementing __complex__ - class MyComplex(object): - def __init__(self, value): - self.value = value - def __complex__(self): - return self.value - - # old-style class implementing __complex__ - class MyComplexOS: - def __init__(self, value): - self.value = value - def __complex__(self): - return self.value - - # classes for which __complex__ raises an exception class SomeException(Exception): pass - class MyComplexException(object): - def __complex__(self): - raise SomeException - class MyComplexExceptionOS: - def __complex__(self): - raise SomeException - - # some classes not providing __float__ or __complex__ - class NeitherComplexNorFloat(object): - pass - class NeitherComplexNorFloatOS: - pass - class Index: - def __int__(self): return 2 - def __index__(self): return 2 - class MyInt: - def __int__(self): return 2 # other possible combinations of __float__ and __complex__ # that should work - class FloatAndComplex(object): + class FloatAndComplex: def __float__(self): return flt_arg def __complex__(self): return cx_arg - class FloatAndComplexOS: - def __float__(self): - return flt_arg - def __complex__(self): - return cx_arg - class JustFloat(object): - def __float__(self): - return flt_arg - class JustFloatOS: - def __float__(self): - return flt_arg for f in self.test_functions: # usual usage - self.assertEqual(f(MyComplex(cx_arg)), f(cx_arg)) - self.assertEqual(f(MyComplexOS(cx_arg)), f(cx_arg)) + self.assertEqual(f(FakeComplex(cx_arg)), f(cx_arg)) # other combinations of __float__ and __complex__ self.assertEqual(f(FloatAndComplex()), f(cx_arg)) - self.assertEqual(f(FloatAndComplexOS()), f(cx_arg)) - self.assertEqual(f(JustFloat()), f(flt_arg)) - self.assertEqual(f(JustFloatOS()), f(flt_arg)) - self.assertEqual(f(Index()), f(int(Index()))) + self.assertEqual(f(FakeFloat(flt_arg)), f(flt_arg)) + self.assertEqual(f(FakeIndex(2)), f(2)) # TypeError should be raised for classes not providing # either __complex__ or __float__, even if they provide - # __int__ or __index__. An old-style class - # currently raises AttributeError instead of a TypeError; - # this could be considered a bug. - self.assertRaises(TypeError, f, NeitherComplexNorFloat()) - self.assertRaises(TypeError, f, MyInt()) - self.assertRaises(Exception, f, NeitherComplexNorFloatOS()) + # __int__. + self.assertRaises(TypeError, f, object()) + self.assertRaises(TypeError, f, FakeInt(2)) # non-complex return value from __complex__ -> TypeError for bad_complex in non_complexes: - self.assertRaises(TypeError, f, MyComplex(bad_complex)) - self.assertRaises(TypeError, f, MyComplexOS(bad_complex)) + self.assertRaises(TypeError, f, FakeComplex(bad_complex)) # exceptions in __complex__ should be propagated correctly - self.assertRaises(SomeException, f, MyComplexException()) - self.assertRaises(SomeException, f, MyComplexExceptionOS()) + self.assertRaises(SomeException, f, FakeComplex(SomeException)) def test_input_type(self): # ints should be acceptable inputs to all cmath diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index dee5c7fa308bd2..782ce92ff18e5a 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -1,5 +1,6 @@ import unittest from test import support +from test.support import FakeIndex, FakeInt, FakeFloat, FakeComplex from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) @@ -215,19 +216,11 @@ def test_conjugate(self): self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) def test_constructor(self): - class OS: - def __init__(self, value): self.value = value - def __complex__(self): return self.value - class NS(object): - def __init__(self, value): self.value = value - def __complex__(self): return self.value - self.assertEqual(complex(OS(1+10j)), 1+10j) - self.assertEqual(complex(NS(1+10j)), 1+10j) - self.assertRaises(TypeError, complex, OS(None)) - self.assertRaises(TypeError, complex, NS(None)) + self.assertEqual(complex(FakeComplex(1+10j)), 1+10j) + self.assertRaises(TypeError, complex, FakeComplex(None)) self.assertRaises(TypeError, complex, {}) - self.assertRaises(TypeError, complex, NS(1.5)) - self.assertRaises(TypeError, complex, NS(1)) + self.assertRaises(TypeError, complex, FakeComplex(1.5)) + self.assertRaises(TypeError, complex, FakeComplex(1)) self.assertAlmostEqual(complex("1+10j"), 1+10j) self.assertAlmostEqual(complex(10), 10+0j) @@ -351,39 +344,19 @@ def split_zeros(x): class EvilExc(Exception): pass - class evilcomplex: - def __complex__(self): - raise EvilExc - - self.assertRaises(EvilExc, complex, evilcomplex()) - - class float2: - def __init__(self, value): - self.value = value - def __float__(self): - return self.value - - self.assertAlmostEqual(complex(float2(42.)), 42) - self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) - self.assertRaises(TypeError, complex, float2(None)) - - class MyIndex: - def __init__(self, value): - self.value = value - def __index__(self): - return self.value + self.assertRaises(EvilExc, complex, FakeComplex(EvilExc)) - self.assertAlmostEqual(complex(MyIndex(42)), 42.0+0.0j) - self.assertAlmostEqual(complex(123, MyIndex(42)), 123.0+42.0j) - self.assertRaises(OverflowError, complex, MyIndex(2**2000)) - self.assertRaises(OverflowError, complex, 123, MyIndex(2**2000)) + self.assertAlmostEqual(complex(FakeFloat(42.)), 42) + self.assertAlmostEqual(complex(real=FakeFloat(17.), imag=FakeFloat(23.)), 17+23j) + self.assertRaises(TypeError, complex, FakeFloat(None)) - class MyInt: - def __int__(self): - return 42 + self.assertAlmostEqual(complex(FakeIndex(42)), 42.0+0.0j) + self.assertAlmostEqual(complex(123, FakeIndex(42)), 123.0+42.0j) + self.assertRaises(OverflowError, complex, FakeIndex(2**2000)) + self.assertRaises(OverflowError, complex, 123, FakeIndex(2**2000)) - self.assertRaises(TypeError, complex, MyInt()) - self.assertRaises(TypeError, complex, 123, MyInt()) + self.assertRaises(TypeError, complex, FakeInt(42)) + self.assertRaises(TypeError, complex, 123, FakeInt(42)) class complex0(complex): """Test usage of __complex__() when inheriting from 'complex'""" diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 9651281e24edbe..3dc0189c90dc16 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -8,6 +8,7 @@ import unittest from test import support +from test.support import FakeIndex, FakeInt, FakeFloat from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) from math import isinf, isnan, copysign, ldexp @@ -173,10 +174,6 @@ def test_float_with_comma(self): def test_floatconversion(self): # Make sure that calls to __float__() work properly - class Foo1(object): - def __float__(self): - return 42. - class Foo2(float): def __float__(self): return 42. @@ -198,45 +195,30 @@ class FooStr(str): def __float__(self): return float(str(self)) + 1 - self.assertEqual(float(Foo1()), 42.) + self.assertEqual(float(FakeFloat(42.)), 42.) self.assertEqual(float(Foo2()), 42.) with self.assertWarns(DeprecationWarning): self.assertEqual(float(Foo3(21)), 42.) self.assertRaises(TypeError, float, Foo4(42)) self.assertEqual(float(FooStr('8')), 9.) - class Foo5: - def __float__(self): - return "" - self.assertRaises(TypeError, time.sleep, Foo5()) + self.assertRaises(TypeError, time.sleep, FakeFloat("")) # Issue #24731 - class F: - def __float__(self): - return OtherFloatSubclass(42.) + f = FakeFloat(OtherFloatSubclass(42.)) with self.assertWarns(DeprecationWarning): - self.assertEqual(float(F()), 42.) + self.assertEqual(float(f), 42.) with self.assertWarns(DeprecationWarning): - self.assertIs(type(float(F())), float) + self.assertIs(type(float(f)), float) with self.assertWarns(DeprecationWarning): - self.assertEqual(FloatSubclass(F()), 42.) + self.assertEqual(FloatSubclass(f), 42.) with self.assertWarns(DeprecationWarning): - self.assertIs(type(FloatSubclass(F())), FloatSubclass) + self.assertIs(type(FloatSubclass(f)), FloatSubclass) - class MyIndex: - def __init__(self, value): - self.value = value - def __index__(self): - return self.value - - self.assertEqual(float(MyIndex(42)), 42.0) - self.assertRaises(OverflowError, float, MyIndex(2**2000)) - - class MyInt: - def __int__(self): - return 42 + self.assertEqual(float(FakeIndex(42)), 42.0) + self.assertRaises(OverflowError, float, FakeIndex(2**2000)) - self.assertRaises(TypeError, float, MyInt()) + self.assertRaises(TypeError, float, FakeInt(42)) def test_keyword_args(self): with self.assertRaisesRegex(TypeError, 'keyword argument'): diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py index 1a73fa4615806d..7bd1cbf0b0e035 100644 --- a/Lib/test/test_getargs2.py +++ b/Lib/test/test_getargs2.py @@ -3,6 +3,7 @@ import string import sys from test import support +from test.support import FakeIndex, FakeInt, FakeFloat, FakeComplex # Skip this test if the _testcapi module isn't available. _testcapi = support.import_module('_testcapi') from _testcapi import getargs_keywords, getargs_keyword_only @@ -53,52 +54,24 @@ LLONG_MIN = -2**63 ULLONG_MAX = 2**64-1 -class Index: - def __index__(self): - return 99 - class IndexIntSubclass(int): def __index__(self): return 99 -class BadIndex: - def __index__(self): - return 1.0 - -class BadIndex2: - def __index__(self): - return True - class BadIndex3(int): def __index__(self): return True -class Int: - def __int__(self): - return 99 - class IntSubclass(int): def __int__(self): return 99 -class BadInt: - def __int__(self): - return 1.0 - -class BadInt2: - def __int__(self): - return True - class BadInt3(int): def __int__(self): return True -class Float: - def __float__(self): - return 4.25 - class FloatSubclass(float): pass @@ -106,23 +79,11 @@ class FloatSubclass2(float): def __float__(self): return 4.25 -class BadFloat: - def __float__(self): - return 687 - -class BadFloat2: - def __float__(self): - return FloatSubclass(4.25) - class BadFloat3(float): def __float__(self): return FloatSubclass(4.25) -class Complex: - def __complex__(self): - return 4.25+0.5j - class ComplexSubclass(complex): pass @@ -130,14 +91,6 @@ class ComplexSubclass2(complex): def __complex__(self): return 4.25+0.5j -class BadComplex: - def __complex__(self): - return 1.25 - -class BadComplex2: - def __complex__(self): - return ComplexSubclass(4.25+0.5j) - class BadComplex3(complex): def __complex__(self): return ComplexSubclass(4.25+0.5j) @@ -155,18 +108,18 @@ def test_b(self): from _testcapi import getargs_b # b returns 'unsigned char', and does range checking (0 ... UCHAR_MAX) self.assertRaises(TypeError, getargs_b, 3.14) - self.assertEqual(99, getargs_b(Index())) + self.assertEqual(99, getargs_b(FakeIndex(99))) self.assertEqual(0, getargs_b(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_b, BadIndex()) + self.assertRaises(TypeError, getargs_b, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_b(BadIndex2())) + self.assertEqual(1, getargs_b(FakeIndex(True))) self.assertEqual(0, getargs_b(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_b(Int())) + self.assertEqual(99, getargs_b(FakeInt(99))) self.assertEqual(0, getargs_b(IntSubclass())) - self.assertRaises(TypeError, getargs_b, BadInt()) + self.assertRaises(TypeError, getargs_b, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_b(BadInt2())) + self.assertEqual(1, getargs_b(FakeInt(True))) self.assertEqual(0, getargs_b(BadInt3())) self.assertRaises(OverflowError, getargs_b, -1) @@ -181,18 +134,18 @@ def test_B(self): from _testcapi import getargs_B # B returns 'unsigned char', no range checking self.assertRaises(TypeError, getargs_B, 3.14) - self.assertEqual(99, getargs_B(Index())) + self.assertEqual(99, getargs_B(FakeIndex(99))) self.assertEqual(0, getargs_B(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_B, BadIndex()) + self.assertRaises(TypeError, getargs_B, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_B(BadIndex2())) + self.assertEqual(1, getargs_B(FakeIndex(True))) self.assertEqual(0, getargs_B(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_B(Int())) + self.assertEqual(99, getargs_B(FakeInt(99))) self.assertEqual(0, getargs_B(IntSubclass())) - self.assertRaises(TypeError, getargs_B, BadInt()) + self.assertRaises(TypeError, getargs_B, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_B(BadInt2())) + self.assertEqual(1, getargs_B(FakeInt(True))) self.assertEqual(0, getargs_B(BadInt3())) self.assertEqual(UCHAR_MAX, getargs_B(-1)) @@ -207,18 +160,18 @@ def test_H(self): from _testcapi import getargs_H # H returns 'unsigned short', no range checking self.assertRaises(TypeError, getargs_H, 3.14) - self.assertEqual(99, getargs_H(Index())) + self.assertEqual(99, getargs_H(FakeIndex(99))) self.assertEqual(0, getargs_H(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_H, BadIndex()) + self.assertRaises(TypeError, getargs_H, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_H(BadIndex2())) + self.assertEqual(1, getargs_H(FakeIndex(True))) self.assertEqual(0, getargs_H(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_H(Int())) + self.assertEqual(99, getargs_H(FakeInt(99))) self.assertEqual(0, getargs_H(IntSubclass())) - self.assertRaises(TypeError, getargs_H, BadInt()) + self.assertRaises(TypeError, getargs_H, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_H(BadInt2())) + self.assertEqual(1, getargs_H(FakeInt(True))) self.assertEqual(0, getargs_H(BadInt3())) self.assertEqual(USHRT_MAX, getargs_H(-1)) @@ -234,18 +187,18 @@ def test_I(self): from _testcapi import getargs_I # I returns 'unsigned int', no range checking self.assertRaises(TypeError, getargs_I, 3.14) - self.assertEqual(99, getargs_I(Index())) + self.assertEqual(99, getargs_I(FakeIndex(99))) self.assertEqual(0, getargs_I(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_I, BadIndex()) + self.assertRaises(TypeError, getargs_I, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_I(BadIndex2())) + self.assertEqual(1, getargs_I(FakeIndex(True))) self.assertEqual(0, getargs_I(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_I(Int())) + self.assertEqual(99, getargs_I(FakeInt(99))) self.assertEqual(0, getargs_I(IntSubclass())) - self.assertRaises(TypeError, getargs_I, BadInt()) + self.assertRaises(TypeError, getargs_I, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_I(BadInt2())) + self.assertEqual(1, getargs_I(FakeInt(True))) self.assertEqual(0, getargs_I(BadInt3())) self.assertEqual(UINT_MAX, getargs_I(-1)) @@ -262,15 +215,15 @@ def test_k(self): # k returns 'unsigned long', no range checking # it does not accept float, or instances with __int__ self.assertRaises(TypeError, getargs_k, 3.14) - self.assertRaises(TypeError, getargs_k, Index()) + self.assertRaises(TypeError, getargs_k, FakeIndex(99)) self.assertEqual(0, getargs_k(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_k, BadIndex()) - self.assertRaises(TypeError, getargs_k, BadIndex2()) + self.assertRaises(TypeError, getargs_k, FakeIndex(1.0)) + self.assertRaises(TypeError, getargs_k, FakeIndex(True)) self.assertEqual(0, getargs_k(BadIndex3())) - self.assertRaises(TypeError, getargs_k, Int()) + self.assertRaises(TypeError, getargs_k, FakeInt(99)) self.assertEqual(0, getargs_k(IntSubclass())) - self.assertRaises(TypeError, getargs_k, BadInt()) - self.assertRaises(TypeError, getargs_k, BadInt2()) + self.assertRaises(TypeError, getargs_k, FakeInt(1.0)) + self.assertRaises(TypeError, getargs_k, FakeInt(True)) self.assertEqual(0, getargs_k(BadInt3())) self.assertEqual(ULONG_MAX, getargs_k(-1)) @@ -287,18 +240,18 @@ def test_h(self): from _testcapi import getargs_h # h returns 'short', and does range checking (SHRT_MIN ... SHRT_MAX) self.assertRaises(TypeError, getargs_h, 3.14) - self.assertEqual(99, getargs_h(Index())) + self.assertEqual(99, getargs_h(FakeIndex(99))) self.assertEqual(0, getargs_h(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_h, BadIndex()) + self.assertRaises(TypeError, getargs_h, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_h(BadIndex2())) + self.assertEqual(1, getargs_h(FakeIndex(True))) self.assertEqual(0, getargs_h(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_h(Int())) + self.assertEqual(99, getargs_h(FakeInt(99))) self.assertEqual(0, getargs_h(IntSubclass())) - self.assertRaises(TypeError, getargs_h, BadInt()) + self.assertRaises(TypeError, getargs_h, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_h(BadInt2())) + self.assertEqual(1, getargs_h(FakeInt(True))) self.assertEqual(0, getargs_h(BadInt3())) self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1) @@ -313,18 +266,18 @@ def test_i(self): from _testcapi import getargs_i # i returns 'int', and does range checking (INT_MIN ... INT_MAX) self.assertRaises(TypeError, getargs_i, 3.14) - self.assertEqual(99, getargs_i(Index())) + self.assertEqual(99, getargs_i(FakeIndex(99))) self.assertEqual(0, getargs_i(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_i, BadIndex()) + self.assertRaises(TypeError, getargs_i, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_i(BadIndex2())) + self.assertEqual(1, getargs_i(FakeIndex(True))) self.assertEqual(0, getargs_i(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_i(Int())) + self.assertEqual(99, getargs_i(FakeInt(99))) self.assertEqual(0, getargs_i(IntSubclass())) - self.assertRaises(TypeError, getargs_i, BadInt()) + self.assertRaises(TypeError, getargs_i, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_i(BadInt2())) + self.assertEqual(1, getargs_i(FakeInt(True))) self.assertEqual(0, getargs_i(BadInt3())) self.assertRaises(OverflowError, getargs_i, INT_MIN-1) @@ -339,18 +292,18 @@ def test_l(self): from _testcapi import getargs_l # l returns 'long', and does range checking (LONG_MIN ... LONG_MAX) self.assertRaises(TypeError, getargs_l, 3.14) - self.assertEqual(99, getargs_l(Index())) + self.assertEqual(99, getargs_l(FakeIndex(99))) self.assertEqual(0, getargs_l(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_l, BadIndex()) + self.assertRaises(TypeError, getargs_l, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_l(BadIndex2())) + self.assertEqual(1, getargs_l(FakeIndex(True))) self.assertEqual(0, getargs_l(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_l(Int())) + self.assertEqual(99, getargs_l(FakeInt(99))) self.assertEqual(0, getargs_l(IntSubclass())) - self.assertRaises(TypeError, getargs_l, BadInt()) + self.assertRaises(TypeError, getargs_l, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_l(BadInt2())) + self.assertEqual(1, getargs_l(FakeInt(True))) self.assertEqual(0, getargs_l(BadInt3())) self.assertRaises(OverflowError, getargs_l, LONG_MIN-1) @@ -366,16 +319,16 @@ def test_n(self): # n returns 'Py_ssize_t', and does range checking # (PY_SSIZE_T_MIN ... PY_SSIZE_T_MAX) self.assertRaises(TypeError, getargs_n, 3.14) - self.assertEqual(99, getargs_n(Index())) + self.assertEqual(99, getargs_n(FakeIndex(99))) self.assertEqual(0, getargs_n(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_n, BadIndex()) + self.assertRaises(TypeError, getargs_n, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_n(BadIndex2())) + self.assertEqual(1, getargs_n(FakeIndex(True))) self.assertEqual(0, getargs_n(BadIndex3())) - self.assertRaises(TypeError, getargs_n, Int()) + self.assertRaises(TypeError, getargs_n, FakeInt(99)) self.assertEqual(0, getargs_n(IntSubclass())) - self.assertRaises(TypeError, getargs_n, BadInt()) - self.assertRaises(TypeError, getargs_n, BadInt2()) + self.assertRaises(TypeError, getargs_n, FakeInt(1.0)) + self.assertRaises(TypeError, getargs_n, FakeInt(True)) self.assertEqual(0, getargs_n(BadInt3())) self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MIN-1) @@ -394,18 +347,18 @@ def test_L(self): # ... LLONG_MAX) self.assertRaises(TypeError, getargs_L, 3.14) self.assertRaises(TypeError, getargs_L, "Hello") - self.assertEqual(99, getargs_L(Index())) + self.assertEqual(99, getargs_L(FakeIndex(99))) self.assertEqual(0, getargs_L(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_L, BadIndex()) + self.assertRaises(TypeError, getargs_L, FakeIndex(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_L(BadIndex2())) + self.assertEqual(1, getargs_L(FakeIndex(True))) self.assertEqual(0, getargs_L(BadIndex3())) with self.assertWarns(DeprecationWarning): - self.assertEqual(99, getargs_L(Int())) + self.assertEqual(99, getargs_L(FakeInt(99))) self.assertEqual(0, getargs_L(IntSubclass())) - self.assertRaises(TypeError, getargs_L, BadInt()) + self.assertRaises(TypeError, getargs_L, FakeInt(1.0)) with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_L(BadInt2())) + self.assertEqual(1, getargs_L(FakeInt(True))) self.assertEqual(0, getargs_L(BadInt3())) self.assertRaises(OverflowError, getargs_L, LLONG_MIN-1) @@ -420,15 +373,15 @@ def test_K(self): from _testcapi import getargs_K # K return 'unsigned long long', no range checking self.assertRaises(TypeError, getargs_K, 3.14) - self.assertRaises(TypeError, getargs_K, Index()) + self.assertRaises(TypeError, getargs_K, FakeIndex(99)) self.assertEqual(0, getargs_K(IndexIntSubclass())) - self.assertRaises(TypeError, getargs_K, BadIndex()) - self.assertRaises(TypeError, getargs_K, BadIndex2()) + self.assertRaises(TypeError, getargs_K, FakeIndex(1.0)) + self.assertRaises(TypeError, getargs_K, FakeIndex(True)) self.assertEqual(0, getargs_K(BadIndex3())) - self.assertRaises(TypeError, getargs_K, Int()) + self.assertRaises(TypeError, getargs_K, FakeInt(99)) self.assertEqual(0, getargs_K(IntSubclass())) - self.assertRaises(TypeError, getargs_K, BadInt()) - self.assertRaises(TypeError, getargs_K, BadInt2()) + self.assertRaises(TypeError, getargs_K, FakeInt(1.0)) + self.assertRaises(TypeError, getargs_K, FakeInt(True)) self.assertEqual(0, getargs_K(BadInt3())) self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX)) @@ -450,15 +403,15 @@ def test_f(self): self.assertEqual(getargs_f(4.25), 4.25) self.assertEqual(getargs_f(4), 4.0) self.assertRaises(TypeError, getargs_f, 4.25+0j) - self.assertEqual(getargs_f(Float()), 4.25) + self.assertEqual(getargs_f(FakeFloat(4.25)), 4.25) self.assertEqual(getargs_f(FloatSubclass(7.5)), 7.5) self.assertEqual(getargs_f(FloatSubclass2(7.5)), 7.5) - self.assertRaises(TypeError, getargs_f, BadFloat()) + self.assertRaises(TypeError, getargs_f, FakeFloat(687)) with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_f(BadFloat2()), 4.25) + self.assertEqual(getargs_f(FakeFloat(FloatSubclass(4.25))), 4.25) self.assertEqual(getargs_f(BadFloat3(7.5)), 7.5) - self.assertEqual(getargs_f(Index()), 99.0) - self.assertRaises(TypeError, getargs_f, Int()) + self.assertEqual(getargs_f(FakeIndex(99)), 99.0) + self.assertRaises(TypeError, getargs_f, FakeInt(99)) for x in (FLT_MIN, -FLT_MIN, FLT_MAX, -FLT_MAX, INF, -INF): self.assertEqual(getargs_f(x), x) @@ -484,15 +437,15 @@ def test_d(self): self.assertEqual(getargs_d(4.25), 4.25) self.assertEqual(getargs_d(4), 4.0) self.assertRaises(TypeError, getargs_d, 4.25+0j) - self.assertEqual(getargs_d(Float()), 4.25) + self.assertEqual(getargs_d(FakeFloat(4.25)), 4.25) self.assertEqual(getargs_d(FloatSubclass(7.5)), 7.5) self.assertEqual(getargs_d(FloatSubclass2(7.5)), 7.5) - self.assertRaises(TypeError, getargs_d, BadFloat()) + self.assertRaises(TypeError, getargs_d, FakeFloat(687)) with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_d(BadFloat2()), 4.25) + self.assertEqual(getargs_d(FakeFloat(FloatSubclass(4.25))), 4.25) self.assertEqual(getargs_d(BadFloat3(7.5)), 7.5) - self.assertEqual(getargs_d(Index()), 99.0) - self.assertRaises(TypeError, getargs_d, Int()) + self.assertEqual(getargs_d(FakeIndex(99)), 99.0) + self.assertRaises(TypeError, getargs_d, FakeInt(99)) for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF): self.assertEqual(getargs_d(x), x) @@ -508,15 +461,15 @@ def test_D(self): self.assertEqual(getargs_D(4.25+0.5j), 4.25+0.5j) self.assertEqual(getargs_D(4.25), 4.25+0j) self.assertEqual(getargs_D(4), 4.0+0j) - self.assertEqual(getargs_D(Complex()), 4.25+0.5j) + self.assertEqual(getargs_D(FakeComplex(4.25+0.5j)), 4.25+0.5j) self.assertEqual(getargs_D(ComplexSubclass(7.5+0.25j)), 7.5+0.25j) self.assertEqual(getargs_D(ComplexSubclass2(7.5+0.25j)), 7.5+0.25j) - self.assertRaises(TypeError, getargs_D, BadComplex()) + self.assertRaises(TypeError, getargs_D, FakeComplex(1.25)) with self.assertWarns(DeprecationWarning): - self.assertEqual(getargs_D(BadComplex2()), 4.25+0.5j) + self.assertEqual(getargs_D(FakeComplex(ComplexSubclass(4.25+0.5j))), 4.25+0.5j) self.assertEqual(getargs_D(BadComplex3(7.5+0.25j)), 7.5+0.25j) - self.assertEqual(getargs_D(Index()), 99.0+0j) - self.assertRaises(TypeError, getargs_D, Int()) + self.assertEqual(getargs_D(FakeIndex(99)), 99.0+0j) + self.assertRaises(TypeError, getargs_D, FakeInt(99)) for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF): c = complex(x, 1.0) diff --git a/Lib/test/test_index.py b/Lib/test/test_index.py index cbdc56c801a4bd..1969271b266281 100644 --- a/Lib/test/test_index.py +++ b/Lib/test/test_index.py @@ -1,44 +1,26 @@ import unittest from test import support +from test.support import FakeIndex import operator maxsize = support.MAX_Py_ssize_t -class newstyle: - def __index__(self): - return self.ind - class TrapInt(int): def __index__(self): return int(self) class BaseTestCase(unittest.TestCase): - def setUp(self): - self.o = newstyle() - self.n = newstyle() - def test_basic(self): - self.o.ind = -2 - self.n.ind = 2 - self.assertEqual(operator.index(self.o), -2) - self.assertEqual(operator.index(self.n), 2) + self.assertEqual(operator.index(FakeIndex(-2)), -2) def test_slice(self): - self.o.ind = 1 - self.n.ind = 2 - slc = slice(self.o, self.o, self.o) - check_slc = slice(1, 1, 1) - self.assertEqual(slc.indices(self.o), check_slc.indices(1)) - slc = slice(self.n, self.n, self.n) + slc = slice(FakeIndex(2), FakeIndex(2), FakeIndex(2)) check_slc = slice(2, 2, 2) - self.assertEqual(slc.indices(self.n), check_slc.indices(2)) + self.assertEqual(slc.indices(FakeIndex(2)), check_slc.indices(2)) def test_wrappers(self): - self.o.ind = 4 - self.n.ind = 5 self.assertEqual(6 .__index__(), 6) self.assertEqual(-7 .__index__(), -7) - self.assertEqual(self.o.__index__(), 4) - self.assertEqual(self.n.__index__(), 5) + self.assertEqual(FakeIndex(5).__index__(), 5) self.assertEqual(True.__index__(), 1) self.assertEqual(False.__index__(), 0) @@ -48,12 +30,8 @@ def test_subclasses(self): self.assertEqual(slice(TrapInt()).indices(0), (0,0,1)) def test_error(self): - self.o.ind = 'dumb' - self.n.ind = 'bad' - self.assertRaises(TypeError, operator.index, self.o) - self.assertRaises(TypeError, operator.index, self.n) - self.assertRaises(TypeError, slice(self.o).indices, 0) - self.assertRaises(TypeError, slice(self.n).indices, 0) + self.assertRaises(TypeError, operator.index, FakeIndex('bad')) + self.assertRaises(TypeError, slice(FakeIndex('bad')).indices, 0) def test_int_subclass_with_index(self): # __index__ should be used when computing indices, even for int @@ -72,15 +50,11 @@ def __index__(self): #self.assertIs(type(operator_index), int) def test_index_returns_int_subclass(self): - class BadInt: - def __index__(self): - return True - class BadInt2(int): def __index__(self): return True - bad_int = BadInt() + bad_int = FakeIndex(True) with self.assertWarns(DeprecationWarning): n = operator.index(bad_int) self.assertEqual(n, 1) @@ -93,105 +67,66 @@ def __index__(self): class SeqTestCase: # This test case isn't run directly. It just defines common tests # to the different sequence types below - def setUp(self): - self.o = newstyle() - self.n = newstyle() - self.o2 = newstyle() - self.n2 = newstyle() def test_index(self): - self.o.ind = -2 - self.n.ind = 2 - self.assertEqual(self.seq[self.n], self.seq[2]) - self.assertEqual(self.seq[self.o], self.seq[-2]) + self.assertEqual(self.seq[FakeIndex(2)], self.seq[2]) + self.assertEqual(self.seq[FakeIndex(-2)], self.seq[-2]) def test_slice(self): - self.o.ind = 1 - self.o2.ind = 3 - self.n.ind = 2 - self.n2.ind = 4 - self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3]) - self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4]) + self.assertEqual(self.seq[FakeIndex(1):FakeIndex(3)], self.seq[1:3]) def test_slice_bug7532(self): seqlen = len(self.seq) - self.o.ind = int(seqlen * 1.5) - self.n.ind = seqlen + 2 - self.assertEqual(self.seq[self.o:], self.seq[0:0]) - self.assertEqual(self.seq[:self.o], self.seq) - self.assertEqual(self.seq[self.n:], self.seq[0:0]) - self.assertEqual(self.seq[:self.n], self.seq) - self.o2.ind = -seqlen - 2 - self.n2.ind = -int(seqlen * 1.5) - self.assertEqual(self.seq[self.o2:], self.seq) - self.assertEqual(self.seq[:self.o2], self.seq[0:0]) - self.assertEqual(self.seq[self.n2:], self.seq) - self.assertEqual(self.seq[:self.n2], self.seq[0:0]) + self.assertEqual(self.seq[FakeIndex(seqlen + 2):], self.seq[0:0]) + self.assertEqual(self.seq[:FakeIndex(seqlen + 2)], self.seq) + self.assertEqual(self.seq[FakeIndex(-seqlen - 2):], self.seq) + self.assertEqual(self.seq[:FakeIndex(-seqlen - 2)], self.seq[0:0]) def test_repeat(self): - self.o.ind = 3 - self.n.ind = 2 - self.assertEqual(self.seq * self.o, self.seq * 3) - self.assertEqual(self.seq * self.n, self.seq * 2) - self.assertEqual(self.o * self.seq, self.seq * 3) - self.assertEqual(self.n * self.seq, self.seq * 2) + self.assertEqual(self.seq * FakeIndex(3), self.seq * 3) + self.assertEqual(FakeIndex(3) * self.seq, self.seq * 3) def test_wrappers(self): - self.o.ind = 4 - self.n.ind = 5 - self.assertEqual(self.seq.__getitem__(self.o), self.seq[4]) - self.assertEqual(self.seq.__mul__(self.o), self.seq * 4) - self.assertEqual(self.seq.__rmul__(self.o), self.seq * 4) - self.assertEqual(self.seq.__getitem__(self.n), self.seq[5]) - self.assertEqual(self.seq.__mul__(self.n), self.seq * 5) - self.assertEqual(self.seq.__rmul__(self.n), self.seq * 5) + self.assertEqual(self.seq.__getitem__(FakeIndex(4)), self.seq[4]) + self.assertEqual(self.seq.__mul__(FakeIndex(4)), self.seq * 4) + self.assertEqual(self.seq.__rmul__(FakeIndex(4)), self.seq * 4) def test_subclasses(self): self.assertEqual(self.seq[TrapInt()], self.seq[0]) def test_error(self): - self.o.ind = 'dumb' - self.n.ind = 'bad' - indexobj = lambda x, obj: obj.seq[x] - self.assertRaises(TypeError, indexobj, self.o, self) - self.assertRaises(TypeError, indexobj, self.n, self) - sliceobj = lambda x, obj: obj.seq[x:] - self.assertRaises(TypeError, sliceobj, self.o, self) - self.assertRaises(TypeError, sliceobj, self.n, self) + with self.assertRaises(TypeError): + self.seq[FakeIndex('bad')] + with self.assertRaises(TypeError): + self.seq[FakeIndex('bad'):] class ListTestCase(SeqTestCase, unittest.TestCase): seq = [0,10,20,30,40,50] def test_setdelitem(self): - self.o.ind = -2 - self.n.ind = 2 lst = list('ab!cdefghi!j') - del lst[self.o] - del lst[self.n] - lst[self.o] = 'X' - lst[self.n] = 'Y' + del lst[FakeIndex(-2)] + del lst[FakeIndex(2)] + lst[FakeIndex(-2)] = 'X' + lst[FakeIndex(2)] = 'Y' self.assertEqual(lst, list('abYdefghXj')) lst = [5, 6, 7, 8, 9, 10, 11] - lst.__setitem__(self.n, "here") + lst.__setitem__(FakeIndex(2), "here") self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11]) - lst.__delitem__(self.n) + lst.__delitem__(FakeIndex(2)) self.assertEqual(lst, [5, 6, 8, 9, 10, 11]) def test_inplace_repeat(self): - self.o.ind = 2 - self.n.ind = 3 lst = [6, 4] - lst *= self.o + lst *= FakeIndex(2) self.assertEqual(lst, [6, 4, 6, 4]) - lst *= self.n - self.assertEqual(lst, [6, 4, 6, 4] * 3) lst = [5, 6, 7, 8, 9, 11] - l2 = lst.__imul__(self.n) + l2 = lst.__imul__(FakeIndex(2)) self.assertIs(l2, lst) - self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3) + self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 2) class NewSeq: @@ -236,8 +171,7 @@ class NewSeqTestCase(SeqTestCase, unittest.TestCase): class RangeTestCase(unittest.TestCase): def test_range(self): - n = newstyle() - n.ind = 5 + n = FakeIndex(5) self.assertEqual(range(1, 20)[n], 6) self.assertEqual(range(1, 20).__getitem__(n), 6) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index 6fdf52ef23f65f..9bf2ff14f21631 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -2,6 +2,7 @@ import unittest from test import support +from test.support import FakeIndex, FakeInt from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) @@ -279,21 +280,15 @@ def test_int_base_bad_types(self): int('0', 5.0) def test_int_base_indexable(self): - class MyIndexable(object): - def __init__(self, value): - self.value = value - def __index__(self): - return self.value - # Check out of range bases. for base in 2**100, -2**100, 1, 37: with self.assertRaises(ValueError): int('43', base) # Check in-range bases. - self.assertEqual(int('101', base=MyIndexable(2)), 5) - self.assertEqual(int('101', base=MyIndexable(10)), 101) - self.assertEqual(int('101', base=MyIndexable(36)), 1 + 36**2) + self.assertEqual(int('101', base=FakeIndex(2)), 5) + self.assertEqual(int('101', base=FakeIndex(10)), 101) + self.assertEqual(int('101', base=FakeIndex(36)), 1 + 36**2) def test_non_numeric_input_types(self): # Test possible non-numeric types for the argument x, including @@ -350,11 +345,7 @@ class MissingMethods(object): pass self.assertRaises(TypeError, int, MissingMethods()) - class Foo0: - def __int__(self): - return 42 - - self.assertEqual(int(Foo0()), 42) + self.assertEqual(int(FakeInt(42)), 42) class Classic: pass @@ -459,35 +450,27 @@ def __int__(self): self.assertRaises(TypeError, int, my_int) def test_int_returns_int_subclass(self): - class BadIndex: - def __index__(self): - return True - class BadIndex2(int): def __index__(self): return True - class BadInt: - def __int__(self): - return True - class BadInt2(int): def __int__(self): return True class TruncReturnsBadIndex: def __trunc__(self): - return BadIndex() + return FakeIndex(True) class TruncReturnsBadInt: def __trunc__(self): - return BadInt() + return FakeInt(True) class TruncReturnsIntSubclass: def __trunc__(self): return True - bad_int = BadIndex() + bad_int = FakeIndex(True) with self.assertWarns(DeprecationWarning): n = int(bad_int) self.assertEqual(n, 1) @@ -498,7 +481,7 @@ def __trunc__(self): self.assertEqual(n, 0) self.assertIs(type(n), int) - bad_int = BadInt() + bad_int = FakeInt(True) with self.assertWarns(DeprecationWarning): n = int(bad_int) self.assertEqual(n, 1) diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index eaa6197bec395c..42b3afc9662358 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1,5 +1,6 @@ import unittest from test import support +from test.support import FakeIndex from itertools import * import weakref from decimal import Decimal @@ -1289,15 +1290,10 @@ def test_islice(self): # Issue #30537: islice can accept integer-like objects as # arguments - class IntLike(object): - def __init__(self, val): - self.val = val - def __index__(self): - return self.val - self.assertEqual(list(islice(range(100), IntLike(10))), list(range(10))) - self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50))), + self.assertEqual(list(islice(range(100), FakeIndex(10))), list(range(10))) + self.assertEqual(list(islice(range(100), FakeIndex(10), FakeIndex(50))), list(range(10, 50))) - self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50), IntLike(5))), + self.assertEqual(list(islice(range(100), FakeIndex(10), FakeIndex(50), FakeIndex(5))), list(range(10,50,5))) def test_takewhile(self): diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 4b848a5e7e5f85..0d6a7edf06e39f 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2,6 +2,7 @@ # XXXX Should not do tests around zero only from test.support import run_unittest, verbose, requires_IEEE_754 +from test.support import FakeIndex, FakeFloat from test import support import unittest import itertools @@ -216,24 +217,9 @@ def result_check(expected, got, ulp_tol=5, abs_tol=0.0): else: return None -class FloatLike: - def __init__(self, value): - self.value = value - - def __float__(self): - return self.value - class IntSubclass(int): pass -# Class providing an __index__ method. -class MyIndexable(object): - def __init__(self, value): - self.value = value - - def __index__(self): - return self.value - class MathTests(unittest.TestCase): def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0): @@ -402,7 +388,7 @@ class TestNoCeil: pass self.assertEqual(math.ceil(TestCeil()), 42) self.assertEqual(math.ceil(FloatCeil()), 42) - self.assertEqual(math.ceil(FloatLike(42.5)), 43) + self.assertEqual(math.ceil(FakeFloat(42.5)), 43) self.assertRaises(TypeError, math.ceil, TestNoCeil()) t = TestNoCeil() @@ -546,7 +532,7 @@ class TestNoFloor: pass self.assertEqual(math.floor(TestFloor()), 42) self.assertEqual(math.floor(FloatFloor()), 42) - self.assertEqual(math.floor(FloatLike(41.9)), 41) + self.assertEqual(math.floor(FakeFloat(41.9)), 41) self.assertRaises(TypeError, math.floor, TestNoFloor()) t = TestNoFloor() @@ -731,7 +717,7 @@ def testGcd(self): self.assertRaises(TypeError, gcd, 120.0, 84) self.assertRaises(TypeError, gcd, 120, 84.0) self.assertRaises(TypeError, gcd, 120, 1, 84.0) - self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12) + self.assertEqual(gcd(FakeIndex(120), FakeIndex(84)), 12) def testHypot(self): from decimal import Decimal @@ -949,19 +935,12 @@ def testIsqrt(self): self.assertIs(type(s), int) self.assertEqual(s, 0) - class IntegerLike(object): - def __init__(self, value): - self.value = value - - def __index__(self): - return self.value - - s = math.isqrt(IntegerLike(1729)) + s = math.isqrt(FakeIndex(1729)) self.assertIs(type(s), int) self.assertEqual(s, 41) with self.assertRaises(ValueError): - math.isqrt(IntegerLike(-3)) + math.isqrt(FakeIndex(-3)) # Non-integer-like things bad_values = [ @@ -1015,7 +994,7 @@ def test_lcm(self): self.assertRaises(TypeError, lcm, 120.0, 84) self.assertRaises(TypeError, lcm, 120, 84.0) self.assertRaises(TypeError, lcm, 120, 0, 84.0) - self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840) + self.assertEqual(lcm(FakeIndex(120), FakeIndex(84)), 840) def testLdexp(self): self.assertRaises(TypeError, math.ldexp) @@ -1502,7 +1481,7 @@ class TestNoTrunc: self.assertRaises(TypeError, math.trunc) self.assertRaises(TypeError, math.trunc, 1, 2) - self.assertRaises(TypeError, math.trunc, FloatLike(23.5)) + self.assertRaises(TypeError, math.trunc, FakeFloat(23.5)) self.assertRaises(TypeError, math.trunc, TestNoTrunc()) def testIsfinite(self): @@ -1848,10 +1827,10 @@ def testPerm(self): self.assertEqual(perm(n, k), 1) self.assertIs(type(perm(n, k)), int) self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20) - self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20) + self.assertEqual(perm(FakeIndex(5), FakeIndex(2)), 20) for k in range(3): self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int) - self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int) + self.assertIs(type(perm(FakeIndex(5), FakeIndex(k))), int) def testComb(self): comb = math.comb @@ -1918,10 +1897,10 @@ def testComb(self): self.assertEqual(comb(n, k), 1) self.assertIs(type(comb(n, k)), int) self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10) - self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10) + self.assertEqual(comb(FakeIndex(5), FakeIndex(2)), 10) for k in range(3): self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int) - self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int) + self.assertIs(type(comb(FakeIndex(5), FakeIndex(k))), int) @requires_IEEE_754 def test_nextafter(self): diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py index 30fa129b50ecba..e23e96afdd9fd9 100644 --- a/Lib/test/test_range.py +++ b/Lib/test/test_range.py @@ -4,7 +4,7 @@ import sys import pickle import itertools -from test.support import ALWAYS_EQ +from test.support import ALWAYS_EQ, FakeIndex # pure Python implementations (3 args only), for comparison def pyrange(start, stop, step): @@ -308,37 +308,19 @@ def __eq__(self, other): def test_user_index_method(self): bignum = 2*sys.maxsize smallnum = 42 - - # User-defined class with an __index__ method - class I: - def __init__(self, n): - self.n = int(n) - def __index__(self): - return self.n - self.assertEqual(list(range(I(bignum), I(bignum + 1))), [bignum]) - self.assertEqual(list(range(I(smallnum), I(smallnum + 1))), [smallnum]) - - # User-defined class with a failing __index__ method - class IX: - def __index__(self): - raise RuntimeError - self.assertRaises(RuntimeError, range, IX()) - - # User-defined class with an invalid __index__ method - class IN: - def __index__(self): - return "not a number" - - self.assertRaises(TypeError, range, IN()) + self.assertEqual(list(range(FakeIndex(bignum), FakeIndex(bignum + 1))), [bignum]) + self.assertEqual(list(range(FakeIndex(smallnum), FakeIndex(smallnum + 1))), [smallnum]) + self.assertRaises(RuntimeError, range, FakeIndex(RuntimeError)) + self.assertRaises(TypeError, range, FakeIndex("not a number")) # Test use of user-defined classes in slice indices. - self.assertEqual(range(10)[:I(5)], range(5)) + self.assertEqual(range(10)[:FakeIndex(5)], range(5)) with self.assertRaises(RuntimeError): - range(0, 10)[:IX()] + range(0, 10)[:FakeIndex(RuntimeError)] with self.assertRaises(TypeError): - range(0, 10)[:IN()] + range(0, 10)[:FakeIndex("not a number")] def test_count(self): self.assertEqual(range(3).count(-1), 0) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 4817d761a22df9..dd6c9c39f7dafe 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,5 +1,5 @@ from test.support import (gc_collect, bigmemtest, _2G, - cpython_only, captured_stdout) + cpython_only, captured_stdout, FakeIndex) import locale import re import sre_compile @@ -418,25 +418,20 @@ def test_re_match(self): self.assertEqual(pat.match('ac').group(1, 'b2', 3), ('a', None, 'c')) def test_group(self): - class Index: - def __init__(self, value): - self.value = value - def __index__(self): - return self.value # A single group m = re.match('(a)(b)', 'ab') self.assertEqual(m.group(), 'ab') self.assertEqual(m.group(0), 'ab') self.assertEqual(m.group(1), 'a') - self.assertEqual(m.group(Index(1)), 'a') + self.assertEqual(m.group(FakeIndex(1)), 'a') self.assertRaises(IndexError, m.group, -1) self.assertRaises(IndexError, m.group, 3) self.assertRaises(IndexError, m.group, 1<<1000) - self.assertRaises(IndexError, m.group, Index(1<<1000)) + self.assertRaises(IndexError, m.group, FakeIndex(1<<1000)) self.assertRaises(IndexError, m.group, 'x') # Multiple groups self.assertEqual(m.group(2, 1), ('b', 'a')) - self.assertEqual(m.group(Index(2), Index(1)), ('b', 'a')) + self.assertEqual(m.group(FakeIndex(2), FakeIndex(1)), ('b', 'a')) def test_match_getitem(self): pat = re.compile('(?:(?Pa)|(?Pb))(?Pc)?') diff --git a/Lib/test/test_slice.py b/Lib/test/test_slice.py index 4ae4142c60c8a8..3eb6cf6589b914 100644 --- a/Lib/test/test_slice.py +++ b/Lib/test/test_slice.py @@ -8,6 +8,7 @@ from pickle import loads, dumps from test import support +from test.support import FakeIndex def evaluate_slice_index(arg): @@ -59,16 +60,6 @@ def slice_indices(slice, length): return start, stop, step -# Class providing an __index__ method. Used for testing slice.indices. - -class MyIndexable(object): - def __init__(self, value): - self.value = value - - def __index__(self): - return self.value - - class SliceTest(unittest.TestCase): def test_constructor(self): @@ -219,10 +210,10 @@ def test_indices(self): # ... but it should be fine to use a custom class that provides index. self.assertEqual(slice(0, 10, 1).indices(5), (0, 5, 1)) - self.assertEqual(slice(MyIndexable(0), 10, 1).indices(5), (0, 5, 1)) - self.assertEqual(slice(0, MyIndexable(10), 1).indices(5), (0, 5, 1)) - self.assertEqual(slice(0, 10, MyIndexable(1)).indices(5), (0, 5, 1)) - self.assertEqual(slice(0, 10, 1).indices(MyIndexable(5)), (0, 5, 1)) + self.assertEqual(slice(FakeIndex(0), 10, 1).indices(5), (0, 5, 1)) + self.assertEqual(slice(0, FakeIndex(10), 1).indices(5), (0, 5, 1)) + self.assertEqual(slice(0, 10, FakeIndex(1)).indices(5), (0, 5, 1)) + self.assertEqual(slice(0, 10, 1).indices(FakeIndex(5)), (0, 5, 1)) def test_setslice_without_getslice(self): tmp = [] diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 4829fbe1b975cf..6354bf6672722b 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -7,6 +7,7 @@ import sys from test import support +from test.support import FakeIndex, FakeInt from test.support.script_helper import assert_python_ok ISBIGENDIAN = sys.byteorder == "big" @@ -260,29 +261,6 @@ def run(self): self.test_one(x) # Some error cases. - class NotAnInt: - def __int__(self): - return 42 - - # Objects with an '__index__' method should be allowed - # to pack as integers. That is assuming the implemented - # '__index__' method returns an 'int'. - class Indexable(object): - def __init__(self, value): - self._value = value - - def __index__(self): - return self._value - - # If the '__index__' method raises a type error, then - # '__int__' should be used with a deprecation warning. - class BadIndex(object): - def __index__(self): - raise TypeError - - def __int__(self): - return 42 - self.assertRaises((TypeError, struct.error), struct.pack, self.format, "a string") @@ -294,14 +272,14 @@ def __int__(self): 3+42j) self.assertRaises((TypeError, struct.error), struct.pack, self.format, - NotAnInt()) + FakeInt(42)) self.assertRaises((TypeError, struct.error), struct.pack, self.format, - BadIndex()) + FakeIndex(TypeError)) # Check for legitimate values from '__index__'. - for obj in (Indexable(0), Indexable(10), Indexable(17), - Indexable(42), Indexable(100), Indexable(127)): + for obj in (FakeIndex(0), FakeIndex(10), FakeIndex(17), + FakeIndex(42), FakeIndex(100), FakeIndex(127)): try: struct.pack(format, obj) except: @@ -309,8 +287,8 @@ def __int__(self): "with '__index__' method") # Check for bogus values from '__index__'. - for obj in (Indexable(b'a'), Indexable('b'), Indexable(None), - Indexable({'a': 1}), Indexable([1, 2, 3])): + for obj in (FakeIndex(b'a'), FakeIndex('b'), FakeIndex(None), + FakeIndex({'a': 1}), FakeIndex([1, 2, 3])): self.assertRaises((TypeError, struct.error), struct.pack, self.format, obj) diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 563507fee3d7ea..2795d1bfe014d6 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -11,7 +11,7 @@ import random from test import support -from test.support import script_helper, ALWAYS_EQ +from test.support import script_helper, ALWAYS_EQ, FakeIndex # Used in ReferencesTestCase.test_ref_created_during_del() . ref_from_del = None @@ -266,10 +266,7 @@ def __bytes__(self): self.assertEqual(bytes(weakref.proxy(instance)), b"bytes") def test_proxy_index(self): - class C: - def __index__(self): - return 10 - o = C() + o = FakeIndex(10) p = weakref.proxy(o) self.assertEqual(operator.index(p), 10) diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index f828b4c737a5fc..05471553f1d74b 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -5,7 +5,7 @@ import pickle import random import sys -from test.support import bigmemtest, _1G, _4G +from test.support import bigmemtest, _1G, _4G, FakeIndex zlib = support.import_module('zlib') @@ -211,7 +211,7 @@ def test_large_bufsize(self, size): def test_custom_bufsize(self): data = HAMLET_SCENE * 10 compressed = zlib.compress(data, 1) - self.assertEqual(zlib.decompress(compressed, 15, CustomInt()), data) + self.assertEqual(zlib.decompress(compressed, 15, FakeIndex(100)), data) @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform') @bigmemtest(size=_4G + 100, memuse=4) @@ -421,7 +421,7 @@ def test_maxlen_custom(self): data = HAMLET_SCENE * 10 compressed = zlib.compress(data, 1) dco = zlib.decompressobj() - self.assertEqual(dco.decompress(compressed, CustomInt()), data[:100]) + self.assertEqual(dco.decompress(compressed, FakeIndex(100)), data[:100]) def test_clear_unconsumed_tail(self): # Issue #12050: calling decompress() without providing max_length @@ -631,7 +631,7 @@ def test_flush_custom_length(self): data = zlib.compress(input, 1) dco = zlib.decompressobj() dco.decompress(data, 1) - self.assertEqual(dco.flush(CustomInt()), input[1:]) + self.assertEqual(dco.flush(FakeIndex(100)), input[1:]) @requires_Compress_copy def test_compresscopy(self): @@ -913,10 +913,5 @@ def choose_lines(source, number, seed=None, generator=random): """ -class CustomInt: - def __index__(self): - return 100 - - if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Tests/2020-03-31-23-39-37.bpo-40129.WAFA9a.rst b/Misc/NEWS.d/next/Tests/2020-03-31-23-39-37.bpo-40129.WAFA9a.rst new file mode 100644 index 00000000000000..42e0c5396a38a2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-03-31-23-39-37.bpo-40129.WAFA9a.rst @@ -0,0 +1,2 @@ +Added classes ``FakeIndex``, ``FakeInt``, ``FakeFloat`` and ``FakeComplex`` +in :mod:`test.support`.