mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update test_{complex,float}.py from 3.13.5 (#5961)
This commit is contained in:
1 parent
04d8d69a8c
commit
ed8d7157d9
3 files changed
+292
-193
No files matched your search
Vendored
+80
@@ -0,0 +1,80 @@
|
||||
# These are shared with test_tokenize and other test modules.
|
||||
#
|
||||
# Note: since several test cases filter out floats by looking for "e" and ".",
|
||||
# don't add hexadecimal literals that contain "e" or "E".
|
||||
VALID_UNDERSCORE_LITERALS = [
|
||||
'0_0_0',
|
||||
'4_2',
|
||||
'1_0000_0000',
|
||||
'0b1001_0100',
|
||||
'0xffff_ffff',
|
||||
'0o5_7_7',
|
||||
'1_00_00.5',
|
||||
'1_00_00.5e5',
|
||||
'1_00_00e5_1',
|
||||
'1e1_0',
|
||||
'.1_4',
|
||||
'.1_4e1',
|
||||
'0b_0',
|
||||
'0x_f',
|
||||
'0o_5',
|
||||
'1_00_00j',
|
||||
'1_00_00.5j',
|
||||
'1_00_00e5_1j',
|
||||
'.1_4j',
|
||||
'(1_2.5+3_3j)',
|
||||
'(.5_6j)',
|
||||
]
|
||||
INVALID_UNDERSCORE_LITERALS = [
|
||||
# Trailing underscores:
|
||||
'0_',
|
||||
'42_',
|
||||
'1.4j_',
|
||||
'0x_',
|
||||
'0b1_',
|
||||
'0xf_',
|
||||
'0o5_',
|
||||
'0 if 1_Else 1',
|
||||
# Underscores in the base selector:
|
||||
'0_b0',
|
||||
'0_xf',
|
||||
'0_o5',
|
||||
# Old-style octal, still disallowed:
|
||||
'0_7',
|
||||
'09_99',
|
||||
# Multiple consecutive underscores:
|
||||
'4_______2',
|
||||
'0.1__4',
|
||||
'0.1__4j',
|
||||
'0b1001__0100',
|
||||
'0xffff__ffff',
|
||||
'0x___',
|
||||
'0o5__77',
|
||||
'1e1__0',
|
||||
'1e1__0j',
|
||||
# Underscore right before a dot:
|
||||
'1_.4',
|
||||
'1_.4j',
|
||||
# Underscore right after a dot:
|
||||
'1._4',
|
||||
'1._4j',
|
||||
'._5',
|
||||
'._5j',
|
||||
# Underscore right after a sign:
|
||||
'1.0e+_1',
|
||||
'1.0e+_1j',
|
||||
# Underscore right before j:
|
||||
'1.4_j',
|
||||
'1.4e5_j',
|
||||
# Underscore right before e:
|
||||
'1_e1',
|
||||
'1.4_e1',
|
||||
'1.4_e1j',
|
||||
# Underscore right after e:
|
||||
'1e_1',
|
||||
'1.4e_1',
|
||||
'1.4e_1j',
|
||||
# Complex cases with parens:
|
||||
'(1+1.5_j_)',
|
||||
'(1+1.5_j)',
|
||||
]
|
||||
Vendored
+207
-190
@@ -1,15 +1,19 @@
|
||||
import unittest
|
||||
import sys
|
||||
from test import support
|
||||
from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
|
||||
INVALID_UNDERSCORE_LITERALS)
|
||||
from test.support.testcase import ComplexesAreIdenticalMixin
|
||||
from test.support.numbers import (
|
||||
VALID_UNDERSCORE_LITERALS,
|
||||
INVALID_UNDERSCORE_LITERALS,
|
||||
)
|
||||
|
||||
from random import random
|
||||
from math import atan2, isnan, copysign
|
||||
from math import isnan, copysign
|
||||
import operator
|
||||
|
||||
INF = float("inf")
|
||||
NAN = float("nan")
|
||||
DBL_MAX = sys.float_info.max
|
||||
# These tests ensure that complex math does the right thing
|
||||
|
||||
ZERO_DIVISION = (
|
||||
@@ -20,7 +24,28 @@ ZERO_DIVISION = (
|
||||
(1, 0+0j),
|
||||
)
|
||||
|
||||
class ComplexTest(unittest.TestCase):
|
||||
class WithIndex:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __index__(self):
|
||||
return self.value
|
||||
|
||||
class WithFloat:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __float__(self):
|
||||
return self.value
|
||||
|
||||
class ComplexSubclass(complex):
|
||||
pass
|
||||
|
||||
class WithComplex:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __complex__(self):
|
||||
return self.value
|
||||
|
||||
class ComplexTest(ComplexesAreIdenticalMixin, unittest.TestCase):
|
||||
|
||||
def assertAlmostEqual(self, a, b):
|
||||
if isinstance(a, complex):
|
||||
@@ -49,29 +74,6 @@ class ComplexTest(unittest.TestCase):
|
||||
# check that relative difference < eps
|
||||
self.assertTrue(abs((x-y)/y) < eps)
|
||||
|
||||
def assertFloatsAreIdentical(self, x, y):
|
||||
"""assert that floats x and y are identical, in the sense that:
|
||||
(1) both x and y are nans, or
|
||||
(2) both x and y are infinities, with the same sign, or
|
||||
(3) both x and y are zeros, with the same sign, or
|
||||
(4) x and y are both finite and nonzero, and x == y
|
||||
|
||||
"""
|
||||
msg = 'floats {!r} and {!r} are not identical'
|
||||
|
||||
if isnan(x) or isnan(y):
|
||||
if isnan(x) and isnan(y):
|
||||
return
|
||||
elif x == y:
|
||||
if x != 0.0:
|
||||
return
|
||||
# both zero; check that signs match
|
||||
elif copysign(1.0, x) == copysign(1.0, y):
|
||||
return
|
||||
else:
|
||||
msg += ': zeros have different signs'
|
||||
self.fail(msg.format(x, y))
|
||||
|
||||
def assertClose(self, x, y, eps=1e-9):
|
||||
"""Return true iff complexes x and y "are close"."""
|
||||
self.assertCloseAbs(x.real, y.real, eps)
|
||||
@@ -303,6 +305,11 @@ class ComplexTest(unittest.TestCase):
|
||||
except OverflowError:
|
||||
pass
|
||||
|
||||
# gh-113841: possible undefined division by 0 in _Py_c_pow()
|
||||
x, y = 9j, 33j**3
|
||||
with self.assertRaises(OverflowError):
|
||||
x**y
|
||||
|
||||
def test_pow_with_small_integer_exponents(self):
|
||||
# Check that small integer exponents are handled identically
|
||||
# regardless of their type.
|
||||
@@ -340,138 +347,93 @@ class ComplexTest(unittest.TestCase):
|
||||
def test_conjugate(self):
|
||||
self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_constructor(self):
|
||||
class NS:
|
||||
def __init__(self, value): self.value = value
|
||||
def __complex__(self): return self.value
|
||||
self.assertEqual(complex(NS(1+10j)), 1+10j)
|
||||
self.assertRaises(TypeError, complex, NS(None))
|
||||
self.assertRaises(TypeError, complex, {})
|
||||
self.assertRaises(TypeError, complex, NS(1.5))
|
||||
self.assertRaises(TypeError, complex, NS(1))
|
||||
self.assertRaises(TypeError, complex, object())
|
||||
self.assertRaises(TypeError, complex, NS(4.25+0.5j), object())
|
||||
def check(z, x, y):
|
||||
self.assertIs(type(z), complex)
|
||||
self.assertFloatsAreIdentical(z.real, x)
|
||||
self.assertFloatsAreIdentical(z.imag, y)
|
||||
|
||||
self.assertAlmostEqual(complex("1+10j"), 1+10j)
|
||||
self.assertAlmostEqual(complex(10), 10+0j)
|
||||
self.assertAlmostEqual(complex(10.0), 10+0j)
|
||||
self.assertAlmostEqual(complex(10), 10+0j)
|
||||
self.assertAlmostEqual(complex(10+0j), 10+0j)
|
||||
self.assertAlmostEqual(complex(1,10), 1+10j)
|
||||
self.assertAlmostEqual(complex(1,10), 1+10j)
|
||||
self.assertAlmostEqual(complex(1,10.0), 1+10j)
|
||||
self.assertAlmostEqual(complex(1,10), 1+10j)
|
||||
self.assertAlmostEqual(complex(1,10), 1+10j)
|
||||
self.assertAlmostEqual(complex(1,10.0), 1+10j)
|
||||
self.assertAlmostEqual(complex(1.0,10), 1+10j)
|
||||
self.assertAlmostEqual(complex(1.0,10), 1+10j)
|
||||
self.assertAlmostEqual(complex(1.0,10.0), 1+10j)
|
||||
self.assertAlmostEqual(complex(3.14+0j), 3.14+0j)
|
||||
self.assertAlmostEqual(complex(3.14), 3.14+0j)
|
||||
self.assertAlmostEqual(complex(314), 314.0+0j)
|
||||
self.assertAlmostEqual(complex(314), 314.0+0j)
|
||||
self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j)
|
||||
self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j)
|
||||
self.assertAlmostEqual(complex(314, 0), 314.0+0j)
|
||||
self.assertAlmostEqual(complex(314, 0), 314.0+0j)
|
||||
self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j)
|
||||
self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j)
|
||||
self.assertAlmostEqual(complex(0j, 3.14), 3.14j)
|
||||
self.assertAlmostEqual(complex(0.0, 3.14), 3.14j)
|
||||
self.assertAlmostEqual(complex("1"), 1+0j)
|
||||
self.assertAlmostEqual(complex("1j"), 1j)
|
||||
self.assertAlmostEqual(complex(), 0)
|
||||
self.assertAlmostEqual(complex("-1"), -1)
|
||||
self.assertAlmostEqual(complex("+1"), +1)
|
||||
self.assertAlmostEqual(complex("(1+2j)"), 1+2j)
|
||||
self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j)
|
||||
self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j)
|
||||
self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j)
|
||||
self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j)
|
||||
self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j)
|
||||
self.assertAlmostEqual(complex("J"), 1j)
|
||||
self.assertAlmostEqual(complex("( j )"), 1j)
|
||||
self.assertAlmostEqual(complex("+J"), 1j)
|
||||
self.assertAlmostEqual(complex("( -j)"), -1j)
|
||||
self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j)
|
||||
self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j)
|
||||
self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j)
|
||||
self.assertEqual(complex('1-1j'), 1.0 - 1j)
|
||||
self.assertEqual(complex('1J'), 1j)
|
||||
check(complex(), 0.0, 0.0)
|
||||
check(complex(10), 10.0, 0.0)
|
||||
check(complex(4.25), 4.25, 0.0)
|
||||
check(complex(4.25+0j), 4.25, 0.0)
|
||||
check(complex(4.25+0.5j), 4.25, 0.5)
|
||||
check(complex(ComplexSubclass(4.25+0.5j)), 4.25, 0.5)
|
||||
check(complex(WithComplex(4.25+0.5j)), 4.25, 0.5)
|
||||
|
||||
class complex2(complex): pass
|
||||
self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
|
||||
self.assertAlmostEqual(complex(real=17, imag=23), 17+23j)
|
||||
self.assertAlmostEqual(complex(real=17+23j), 17+23j)
|
||||
self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j)
|
||||
self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j)
|
||||
check(complex(1, 10), 1.0, 10.0)
|
||||
check(complex(1, 10.0), 1.0, 10.0)
|
||||
check(complex(1, 4.25), 1.0, 4.25)
|
||||
check(complex(1.0, 10), 1.0, 10.0)
|
||||
check(complex(4.25, 10), 4.25, 10.0)
|
||||
check(complex(1.0, 10.0), 1.0, 10.0)
|
||||
check(complex(4.25, 0.5), 4.25, 0.5)
|
||||
|
||||
check(complex(4.25+0j, 0), 4.25, 0.0)
|
||||
check(complex(ComplexSubclass(4.25+0j), 0), 4.25, 0.0)
|
||||
check(complex(WithComplex(4.25+0j), 0), 4.25, 0.0)
|
||||
check(complex(4.25j, 0), 0.0, 4.25)
|
||||
check(complex(0j, 4.25), 0.0, 4.25)
|
||||
check(complex(0, 4.25+0j), 0.0, 4.25)
|
||||
check(complex(0, ComplexSubclass(4.25+0j)), 0.0, 4.25)
|
||||
with self.assertRaisesRegex(TypeError,
|
||||
"second argument must be a number, not 'WithComplex'"):
|
||||
complex(0, WithComplex(4.25+0j))
|
||||
check(complex(0.0, 4.25j), -4.25, 0.0)
|
||||
check(complex(4.25+0j, 0j), 4.25, 0.0)
|
||||
check(complex(4.25j, 0j), 0.0, 4.25)
|
||||
check(complex(0j, 4.25+0j), 0.0, 4.25)
|
||||
check(complex(0j, 4.25j), -4.25, 0.0)
|
||||
|
||||
check(complex(real=4.25), 4.25, 0.0)
|
||||
check(complex(real=4.25+0j), 4.25, 0.0)
|
||||
check(complex(real=4.25+1.5j), 4.25, 1.5)
|
||||
check(complex(imag=1.5), 0.0, 1.5)
|
||||
check(complex(real=4.25, imag=1.5), 4.25, 1.5)
|
||||
check(complex(4.25, imag=1.5), 4.25, 1.5)
|
||||
|
||||
# check that the sign of a zero in the real or imaginary part
|
||||
# is preserved when constructing from two floats. (These checks
|
||||
# are harmless on systems without support for signed zeros.)
|
||||
def split_zeros(x):
|
||||
"""Function that produces different results for 0. and -0."""
|
||||
return atan2(x, -1.)
|
||||
# is preserved when constructing from two floats.
|
||||
for x in 1.0, -1.0:
|
||||
for y in 0.0, -0.0:
|
||||
check(complex(x, y), x, y)
|
||||
check(complex(y, x), y, x)
|
||||
|
||||
self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.))
|
||||
self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.))
|
||||
self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.))
|
||||
self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.))
|
||||
c = complex(4.25, 1.5)
|
||||
self.assertIs(complex(c), c)
|
||||
c2 = ComplexSubclass(c)
|
||||
self.assertEqual(c2, c)
|
||||
self.assertIs(type(c2), ComplexSubclass)
|
||||
del c, c2
|
||||
|
||||
c = 3.14 + 1j
|
||||
self.assertTrue(complex(c) is c)
|
||||
del c
|
||||
|
||||
self.assertRaises(TypeError, complex, "1", "1")
|
||||
self.assertRaises(TypeError, complex, 1, "1")
|
||||
|
||||
# SF bug 543840: complex(string) accepts strings with \0
|
||||
# Fixed in 2.3.
|
||||
self.assertRaises(ValueError, complex, '1+1j\0j')
|
||||
|
||||
self.assertRaises(TypeError, int, 5+3j)
|
||||
self.assertRaises(TypeError, int, 5+3j)
|
||||
self.assertRaises(TypeError, float, 5+3j)
|
||||
self.assertRaises(ValueError, complex, "")
|
||||
self.assertRaises(TypeError, complex, None)
|
||||
self.assertRaisesRegex(TypeError, "not 'NoneType'", complex, None)
|
||||
self.assertRaises(ValueError, complex, "\0")
|
||||
self.assertRaises(ValueError, complex, "3\09")
|
||||
self.assertRaises(TypeError, complex, "1", "2")
|
||||
self.assertRaises(TypeError, complex, "1", 42)
|
||||
self.assertRaises(TypeError, complex, 1, "2")
|
||||
self.assertRaises(ValueError, complex, "1+")
|
||||
self.assertRaises(ValueError, complex, "1+1j+1j")
|
||||
self.assertRaises(ValueError, complex, "--")
|
||||
self.assertRaises(ValueError, complex, "(1+2j")
|
||||
self.assertRaises(ValueError, complex, "1+2j)")
|
||||
self.assertRaises(ValueError, complex, "1+(2j)")
|
||||
self.assertRaises(ValueError, complex, "(1+2j)123")
|
||||
self.assertRaises(ValueError, complex, "x")
|
||||
self.assertRaises(ValueError, complex, "1j+2")
|
||||
self.assertRaises(ValueError, complex, "1e1ej")
|
||||
self.assertRaises(ValueError, complex, "1e++1ej")
|
||||
self.assertRaises(ValueError, complex, ")1+2j(")
|
||||
self.assertRaisesRegex(
|
||||
TypeError,
|
||||
self.assertRaisesRegex(TypeError,
|
||||
"first argument must be a string or a number, not 'dict'",
|
||||
complex, {1:2}, 1)
|
||||
self.assertRaisesRegex(
|
||||
TypeError,
|
||||
complex, {})
|
||||
self.assertRaisesRegex(TypeError,
|
||||
"first argument must be a string or a number, not 'NoneType'",
|
||||
complex, None)
|
||||
self.assertRaisesRegex(TypeError,
|
||||
"first argument must be a string or a number, not 'dict'",
|
||||
complex, {1:2}, 0)
|
||||
self.assertRaisesRegex(TypeError,
|
||||
"can't take second arg if first is a string",
|
||||
complex, '1', 0)
|
||||
self.assertRaisesRegex(TypeError,
|
||||
"second argument must be a number, not 'dict'",
|
||||
complex, 1, {1:2})
|
||||
# the following three are accepted by Python 2.6
|
||||
self.assertRaises(ValueError, complex, "1..1j")
|
||||
self.assertRaises(ValueError, complex, "1.11.1j")
|
||||
self.assertRaises(ValueError, complex, "1e1.1j")
|
||||
complex, 0, {1:2})
|
||||
self.assertRaisesRegex(TypeError,
|
||||
"second arg can't be a string",
|
||||
complex, 0, '1')
|
||||
|
||||
# check that complex accepts long unicode strings
|
||||
self.assertEqual(type(complex("1"*500)), complex)
|
||||
# check whitespace processing
|
||||
self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j)
|
||||
# Invalid unicode string
|
||||
# See bpo-34087
|
||||
self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f')
|
||||
self.assertRaises(TypeError, complex, WithComplex(1.5))
|
||||
self.assertRaises(TypeError, complex, WithComplex(1))
|
||||
self.assertRaises(TypeError, complex, WithComplex(None))
|
||||
self.assertRaises(TypeError, complex, WithComplex(4.25+0j), object())
|
||||
self.assertRaises(TypeError, complex, WithComplex(1.5), object())
|
||||
self.assertRaises(TypeError, complex, WithComplex(1), object())
|
||||
self.assertRaises(TypeError, complex, WithComplex(None), object())
|
||||
|
||||
class EvilExc(Exception):
|
||||
pass
|
||||
@@ -482,33 +444,33 @@ class ComplexTest(unittest.TestCase):
|
||||
|
||||
self.assertRaises(EvilExc, complex, evilcomplex())
|
||||
|
||||
class float2:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __float__(self):
|
||||
return self.value
|
||||
check(complex(WithFloat(4.25)), 4.25, 0.0)
|
||||
check(complex(WithFloat(4.25), 1.5), 4.25, 1.5)
|
||||
check(complex(1.5, WithFloat(4.25)), 1.5, 4.25)
|
||||
self.assertRaises(TypeError, complex, WithFloat(42))
|
||||
self.assertRaises(TypeError, complex, WithFloat(42), 1.5)
|
||||
self.assertRaises(TypeError, complex, 1.5, WithFloat(42))
|
||||
self.assertRaises(TypeError, complex, WithFloat(None))
|
||||
self.assertRaises(TypeError, complex, WithFloat(None), 1.5)
|
||||
self.assertRaises(TypeError, complex, 1.5, WithFloat(None))
|
||||
|
||||
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.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))
|
||||
check(complex(WithIndex(42)), 42.0, 0.0)
|
||||
check(complex(WithIndex(42), 1.5), 42.0, 1.5)
|
||||
check(complex(1.5, WithIndex(42)), 1.5, 42.0)
|
||||
self.assertRaises(OverflowError, complex, WithIndex(2**2000))
|
||||
self.assertRaises(OverflowError, complex, WithIndex(2**2000), 1.5)
|
||||
self.assertRaises(OverflowError, complex, 1.5, WithIndex(2**2000))
|
||||
self.assertRaises(TypeError, complex, WithIndex(None))
|
||||
self.assertRaises(TypeError, complex, WithIndex(None), 1.5)
|
||||
self.assertRaises(TypeError, complex, 1.5, WithIndex(None))
|
||||
|
||||
class MyInt:
|
||||
def __int__(self):
|
||||
return 42
|
||||
|
||||
self.assertRaises(TypeError, complex, MyInt())
|
||||
self.assertRaises(TypeError, complex, 123, MyInt())
|
||||
self.assertRaises(TypeError, complex, MyInt(), 1.5)
|
||||
self.assertRaises(TypeError, complex, 1.5, MyInt())
|
||||
|
||||
class complex0(complex):
|
||||
"""Test usage of __complex__() when inheriting from 'complex'"""
|
||||
@@ -528,9 +490,9 @@ class ComplexTest(unittest.TestCase):
|
||||
def __complex__(self):
|
||||
return None
|
||||
|
||||
self.assertEqual(complex(complex0(1j)), 42j)
|
||||
check(complex(complex0(1j)), 0.0, 42.0)
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
self.assertEqual(complex(complex1(1j)), 2j)
|
||||
check(complex(complex1(1j)), 0.0, 2.0)
|
||||
self.assertRaises(TypeError, complex, complex2(1j))
|
||||
|
||||
def test___complex__(self):
|
||||
@@ -538,36 +500,93 @@ class ComplexTest(unittest.TestCase):
|
||||
self.assertEqual(z.__complex__(), z)
|
||||
self.assertEqual(type(z.__complex__()), complex)
|
||||
|
||||
class complex_subclass(complex):
|
||||
pass
|
||||
|
||||
z = complex_subclass(3 + 4j)
|
||||
z = ComplexSubclass(3 + 4j)
|
||||
self.assertEqual(z.__complex__(), 3 + 4j)
|
||||
self.assertEqual(type(z.__complex__()), complex)
|
||||
|
||||
@support.requires_IEEE_754
|
||||
def test_constructor_special_numbers(self):
|
||||
class complex2(complex):
|
||||
pass
|
||||
for x in 0.0, -0.0, INF, -INF, NAN:
|
||||
for y in 0.0, -0.0, INF, -INF, NAN:
|
||||
with self.subTest(x=x, y=y):
|
||||
z = complex(x, y)
|
||||
self.assertFloatsAreIdentical(z.real, x)
|
||||
self.assertFloatsAreIdentical(z.imag, y)
|
||||
z = complex2(x, y)
|
||||
self.assertIs(type(z), complex2)
|
||||
z = ComplexSubclass(x, y)
|
||||
self.assertIs(type(z), ComplexSubclass)
|
||||
self.assertFloatsAreIdentical(z.real, x)
|
||||
self.assertFloatsAreIdentical(z.imag, y)
|
||||
z = complex(complex2(x, y))
|
||||
z = complex(ComplexSubclass(x, y))
|
||||
self.assertIs(type(z), complex)
|
||||
self.assertFloatsAreIdentical(z.real, x)
|
||||
self.assertFloatsAreIdentical(z.imag, y)
|
||||
z = complex2(complex(x, y))
|
||||
self.assertIs(type(z), complex2)
|
||||
z = ComplexSubclass(complex(x, y))
|
||||
self.assertIs(type(z), ComplexSubclass)
|
||||
self.assertFloatsAreIdentical(z.real, x)
|
||||
self.assertFloatsAreIdentical(z.imag, y)
|
||||
|
||||
def test_constructor_from_string(self):
|
||||
def check(z, x, y):
|
||||
self.assertIs(type(z), complex)
|
||||
self.assertFloatsAreIdentical(z.real, x)
|
||||
self.assertFloatsAreIdentical(z.imag, y)
|
||||
|
||||
check(complex("1"), 1.0, 0.0)
|
||||
check(complex("1j"), 0.0, 1.0)
|
||||
check(complex("-1"), -1.0, 0.0)
|
||||
check(complex("+1"), 1.0, 0.0)
|
||||
check(complex("1+2j"), 1.0, 2.0)
|
||||
check(complex("(1+2j)"), 1.0, 2.0)
|
||||
check(complex("(1.5+4.25j)"), 1.5, 4.25)
|
||||
check(complex("4.25+1J"), 4.25, 1.0)
|
||||
check(complex(" ( +4.25-6J )"), 4.25, -6.0)
|
||||
check(complex(" ( +4.25-J )"), 4.25, -1.0)
|
||||
check(complex(" ( +4.25+j )"), 4.25, 1.0)
|
||||
check(complex("J"), 0.0, 1.0)
|
||||
check(complex("( j )"), 0.0, 1.0)
|
||||
check(complex("+J"), 0.0, 1.0)
|
||||
check(complex("( -j)"), 0.0, -1.0)
|
||||
check(complex('1-1j'), 1.0, -1.0)
|
||||
check(complex('1J'), 0.0, 1.0)
|
||||
|
||||
check(complex('1e-500'), 0.0, 0.0)
|
||||
check(complex('-1e-500j'), 0.0, -0.0)
|
||||
check(complex('1e-500+1e-500j'), 0.0, 0.0)
|
||||
check(complex('-1e-500+1e-500j'), -0.0, 0.0)
|
||||
check(complex('1e-500-1e-500j'), 0.0, -0.0)
|
||||
check(complex('-1e-500-1e-500j'), -0.0, -0.0)
|
||||
|
||||
# SF bug 543840: complex(string) accepts strings with \0
|
||||
# Fixed in 2.3.
|
||||
self.assertRaises(ValueError, complex, '1+1j\0j')
|
||||
self.assertRaises(ValueError, complex, "")
|
||||
self.assertRaises(ValueError, complex, "\0")
|
||||
self.assertRaises(ValueError, complex, "3\09")
|
||||
self.assertRaises(ValueError, complex, "1+")
|
||||
self.assertRaises(ValueError, complex, "1+1j+1j")
|
||||
self.assertRaises(ValueError, complex, "--")
|
||||
self.assertRaises(ValueError, complex, "(1+2j")
|
||||
self.assertRaises(ValueError, complex, "1+2j)")
|
||||
self.assertRaises(ValueError, complex, "1+(2j)")
|
||||
self.assertRaises(ValueError, complex, "(1+2j)123")
|
||||
self.assertRaises(ValueError, complex, "x")
|
||||
self.assertRaises(ValueError, complex, "1j+2")
|
||||
self.assertRaises(ValueError, complex, "1e1ej")
|
||||
self.assertRaises(ValueError, complex, "1e++1ej")
|
||||
self.assertRaises(ValueError, complex, ")1+2j(")
|
||||
# the following three are accepted by Python 2.6
|
||||
self.assertRaises(ValueError, complex, "1..1j")
|
||||
self.assertRaises(ValueError, complex, "1.11.1j")
|
||||
self.assertRaises(ValueError, complex, "1e1.1j")
|
||||
|
||||
# check that complex accepts long unicode strings
|
||||
self.assertIs(type(complex("1"*500)), complex)
|
||||
# check whitespace processing
|
||||
self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j)
|
||||
# Invalid unicode string
|
||||
# See bpo-34087
|
||||
self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f')
|
||||
|
||||
def test_constructor_negative_nans_from_string(self):
|
||||
self.assertEqual(copysign(1., complex("-nan").real), -1.)
|
||||
self.assertEqual(copysign(1., complex("-nanj").imag), -1.)
|
||||
@@ -589,7 +608,7 @@ class ComplexTest(unittest.TestCase):
|
||||
def test_hash(self):
|
||||
for x in range(-30, 30):
|
||||
self.assertEqual(hash(x), hash(complex(x, 0)))
|
||||
x /= 3.0 # now check against floating point
|
||||
x /= 3.0 # now check against floating-point
|
||||
self.assertEqual(hash(x), hash(complex(x, 0.)))
|
||||
|
||||
self.assertNotEqual(hash(2000005 - 1j), -1)
|
||||
@@ -599,6 +618,8 @@ class ComplexTest(unittest.TestCase):
|
||||
for num in nums:
|
||||
self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num))
|
||||
|
||||
self.assertRaises(OverflowError, abs, complex(DBL_MAX, DBL_MAX))
|
||||
|
||||
def test_repr_str(self):
|
||||
def test(v, expected, test_fn=self.assertEqual):
|
||||
test_fn(repr(v), expected)
|
||||
@@ -644,9 +665,6 @@ class ComplexTest(unittest.TestCase):
|
||||
test(complex(-0., -0.), "(-0-0j)")
|
||||
|
||||
def test_pos(self):
|
||||
class ComplexSubclass(complex):
|
||||
pass
|
||||
|
||||
self.assertEqual(+(1+6j), 1+6j)
|
||||
self.assertEqual(+ComplexSubclass(1, 6), 1+6j)
|
||||
self.assertIs(type(+ComplexSubclass(1, 6)), complex)
|
||||
@@ -666,8 +684,8 @@ class ComplexTest(unittest.TestCase):
|
||||
def test_plus_minus_0j(self):
|
||||
# test that -0j and 0j literals are not identified
|
||||
z1, z2 = 0j, -0j
|
||||
self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.))
|
||||
self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.))
|
||||
self.assertFloatsAreIdentical(z1.imag, 0.0)
|
||||
self.assertFloatsAreIdentical(z2.imag, -0.0)
|
||||
|
||||
@support.requires_IEEE_754
|
||||
def test_negated_imaginary_literal(self):
|
||||
@@ -702,8 +720,7 @@ class ComplexTest(unittest.TestCase):
|
||||
for y in vals:
|
||||
z = complex(x, y)
|
||||
roundtrip = complex(repr(z))
|
||||
self.assertFloatsAreIdentical(z.real, roundtrip.real)
|
||||
self.assertFloatsAreIdentical(z.imag, roundtrip.imag)
|
||||
self.assertComplexesAreIdentical(z, roundtrip)
|
||||
|
||||
# if we predefine some constants, then eval(repr(z)) should
|
||||
# also work, except that it might change the sign of zeros
|
||||
|
||||
Vendored
+5
-3
@@ -9,8 +9,10 @@ import unittest
|
||||
|
||||
from test import support
|
||||
from test.support.testcase import FloatsAreIdenticalMixin
|
||||
from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
|
||||
INVALID_UNDERSCORE_LITERALS)
|
||||
from test.support.numbers import (
|
||||
VALID_UNDERSCORE_LITERALS,
|
||||
INVALID_UNDERSCORE_LITERALS,
|
||||
)
|
||||
from math import isinf, isnan, copysign, ldexp
|
||||
import math
|
||||
|
||||
@@ -1513,4 +1515,4 @@ class HexFloatTestCase(FloatsAreIdenticalMixin, unittest.TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user