Show test_numtypes.py syntax highlighted
#####################################################################################
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# This source code is subject to terms and conditions of the Shared Source License
# for IronPython. A copy of the license can be found in the License.html file
# at the root of this distribution. If you can not locate the Shared Source License
# for IronPython, please send an email to ironpy@microsoft.com.
# By using this source code in any fashion, you are agreeing to be bound by
# the terms of the Shared Source License for IronPython.
#
# You must not remove this notice, or any other, from this software.
#
######################################################################################
"""
This test validates integrity of the operators implemented on the .NET data types
(Byte, SByte, ... UInt64, Single, Double). It does so by evaluating given operator
using standard Python types (int, long, float) and then comparing the results with
results produced by the operators implemented on the .NET types.
"""
from lib.assert_util import *
from operator import add, sub, mul, div, mod, and_, or_, xor, floordiv, truediv, lshift, rshift, neg, pos, abs, invert
if is_cli:
from System import Boolean, Byte, UInt16, UInt32, UInt64, SByte, Int16, Int32, Int64, Single, Double
import clr
class myint(int): pass
class mylong(long): pass
class myfloat(float): pass
class mycomplex(complex): pass
biops = [
("add", add),
("sub", sub),
("mul", mul),
("div", div),
("floordiv", floordiv),
("truediv", truediv),
("mod", mod),
("and", and_),
("or", or_),
("xor", xor),
("pow", pow),
("lshift", lshift),
("rshift", rshift),
("divmod", divmod),
]
unops = [
("neg", neg),
("pos", pos),
("abs", abs),
("invert", invert),
]
def get_clr_values(string, types):
clr_values = []
for t in types:
try:
r = t.Parse(string)
clr_values.append(r)
except: # do not include values that cannot be parsed as given type
pass
return clr_values
# Some values are not generated (myint, mylong, myfloat) because of the semantic difference
# between calling (2L).__div__(single) and (mylong(2L)).__div__(single)
def get_values(values, itypes, ftypes):
"""
This will return structure of values converted to variety of types as a list of tuples:
[ ...
( python_value, [ all_values ] ),
... ]
all_values: Byte, UInt16, UInt32, UInt64, SByte, Int16, Int32, Int64, Single, Double, myint, mylong, myfloat
"""
all = []
for v in values:
sv = str(v)
py = int(v)
clr = get_clr_values(sv, itypes)
clr.append(long(py))
clr.append(myint(py))
clr.append(mylong(py))
all.append( (py, clr) )
py = long(v)
clr = get_clr_values(sv, itypes)
clr.append(py)
clr.append(myint(py))
clr.append(mylong(py))
all.append( (py, clr) )
py = float(v)
clr = get_clr_values(sv, ftypes)
clr.append(myfloat(py))
all.append( (py, clr) )
for imag in [0j, 1j, -1j]:
py = complex(v + imag)
all.append( (py, [ py, mycomplex(py) ] ) )
all.append( (True, [ True ] ))
all.append( (False, [ False ] ))
return all
def mystr(x):
if isinstance(x, tuple):
return "(" + ", ".join(mystr(e) for e in x) + ")"
elif isinstance(x, Single):
return str(round(float(str(x)), 3))
elif isinstance(x, Double):
return str(round(x, 3))
else:
s = str(x)
if s.endswith("L"): return s[:-1]
else: return s
def get_message(a, b, op, x_s, x_v, g_s, g_v):
return """
Math test failed, operation: %(op)s
%(op)s( (%(ta)s) (%(a)s), (%(tb)s) (%(b)s) )
Expected: (%(x_s)s, %(x_v)s)
Got: (%(g_s)s, %(g_v)s)
""" % {
'ta' : str(a.GetType()),
'tb' : str(b.GetType()),
'a' : str(a),
'b' : str(b),
'op' : str(op),
'x_s' : str(x_s),
'x_v' : str(x_v),
'g_s' : str(g_s),
'g_v' : str(g_v)
}
def get_messageun(a, op, x_s, x_v, g_s, g_v):
return """
Math test failed, operation: %(op)s
%(op)s( (%(ta)s) (%(a)s) )
Expected: (%(x_s)s, %(x_v)s)
Got: (%(g_s)s, %(g_v)s)
""" % {
'ta' : str(a.GetType()),
'a' : str(a),
'op' : str(op),
'x_s' : str(x_s),
'x_v' : str(x_v),
'g_s' : str(g_s),
'g_v' : str(g_v)
}
def verify_b(a, b, op, x_s, x_v, g_s, g_v):
Assert(x_s == g_s, get_message(a, b, op, x_s, x_v, g_s, g_v))
if x_s:
# same value
Assert(mystr(x_v) == mystr(g_v), get_message(a, b, op, x_s, x_v, g_s, g_v))
else:
# same exception
Assert(type(x_v) == type(g_v), get_message(a, b, op, x_s, x_v, g_s, g_v))
def verify_u(a, op, x_s, x_v, g_s, g_v):
Assert(x_s == g_s, get_messageun(a, op, x_s, x_v, g_s, g_v))
if x_s:
# same value
Assert(mystr(x_v) == mystr(g_v), get_messageun(a, op, x_s, x_v, g_s, g_v))
else:
# unary operator should never fail
Assert(type(x_v) == type(g_v), get_messageun(a, op, x_s, x_v, g_s, g_v))
def calc(op, *args):
try:
return True, op(*args)
except Exception, e:
return False, e
def verify_implemented_b(implemented, op, a, b):
if not implemented:
Fail("Operation not defined: %(op)s( (%(ta)s) (%(a)s), (%(tb)s) (%(b)s) )" % {
'op' : op, 'ta' : str(a.GetType()), 'tb' : str(b.GetType()), 'a' : str(a), 'b' : str(b)
})
def verify_implemented_u(implemented, op, a):
if not implemented:
Fail("Operation not defined: %(op)s( (%(ta)s) (%(a)s))" % { 'op' : op, 'ta' : str(a.GetType()), 'a' : str(a), })
def extensible(l, r):
ii = isinstance
return ii(l, myint) or ii(l, mylong) or ii(l, myfloat) or ii(l, mycomplex) or ii(r, myint) or ii(r, mylong) or ii(r, myfloat) or ii(r, mycomplex)
def validate_binary_ops(all):
total = 0
last = 0
for l_rec in all:
for r_rec in all:
py_l, clr_l = l_rec
py_r, clr_r = r_rec
for name, bin in biops:
x_s, x_v = calc(bin, py_l, py_r)
for l in clr_l:
for r in clr_r:
implemented = False
# direct binary operator
g_s, g_v = calc(bin, l, r)
if g_v != NotImplemented:
implemented = True
verify_b(l, r, name, x_s, x_v, g_s, g_v)
total += 1
# call __xxx__ and __rxxx__ for non-extensibled types only
if not extensible(l, r):
# l.__xxx__(r)
m_name = "__" + name + "__"
if hasattr(l, m_name):
m = getattr(l, m_name)
g_s, g_v = calc(m, r)
if g_v != NotImplemented:
implemented = True
verify_b(l, r, m_name, x_s, x_v, g_s, g_v)
total += 1
# r.__rxxx__(l)
m_name = "__r" + name + "__"
if hasattr(r, m_name):
m = getattr(r, m_name)
g_s, g_v = calc(m, l)
if g_v != NotImplemented:
implemented = True
verify_b(l, r, m_name, x_s, x_v, g_s, g_v)
total += 1
verify_implemented_b(implemented, name, l, r)
if total - last > 100000:
print ".",
last = total
return total
def validate_unary_ops(all):
total = 0
for l_rec in all:
py_l, clr_l = l_rec
for name, un in unops:
x_s, x_v = calc(un, py_l)
for l in clr_l:
implemented = False
# direct unary operator
g_s, g_v = calc(un, l)
if g_v != NotImplemented:
implemented = True
verify_u(l, name, x_s, x_v, g_s, g_v)
total += 1
# l.__xxx__()
m_name = "__" + name + "__"
if hasattr(l, m_name):
m = getattr(l, m_name)
g_s, g_v = calc(m)
if g_v != NotImplemented:
implemented = True
verify_u(l, m_name, x_s, x_v, g_s, g_v)
total += 1
verify_implemented_u(implemented, name, l)
return total
def validate_constructors(values):
types = [Byte, UInt16, UInt32, UInt64, SByte, Int16, Int32, Int64]
total = 0
for value in values:
for first in types:
v1 = first(value)
for second in types:
v2 = first(second((value)))
total += 1
return total
def test_numeric_types():
values = [-2, -3, -5, 2, 3, 5, 0]
itypes = [Byte, UInt16, UInt32, UInt64, SByte, Int16, Int32, Int64]
ftypes = [Single, Double]
all = get_values(values, itypes, ftypes)
# binaries
total = 0
total += validate_binary_ops(all)
total += validate_unary_ops(all)
total += validate_constructors(values)
print total, "tests ran."
if is_cli:
test_numeric_types()
See more files for this project here