def test_serializing_named_tuples_in_loop(self): NT = Forward("NT") NT = NT.define(NamedTuple(x=OneOf(int, float), y=OneOf(int, TupleOf(NT)))) context = SerializationContext({'NT': NT}) self.serializeInLoop(lambda: NT(x=10, y=(NT(x=20, y=2),)), context=context)
def List(T): ListT = Forward("ListT") return ListT.define( Alternative("List", Node={ "head": T, "tail": ListT }, Empty={}))
def test_serialize_alternatives_as_types(self): A = Forward("A") A = A.define(Alternative("A", X={'a': int}, Y={'a': A})) ts = SerializationContext({'A': A}) self.assertIs(ping_pong(A, ts), A) self.assertIs(ping_pong(A.X, ts), A.X)
def test_class_in_forward(self): class C(Class): x = Member(int) Fwd = Forward("Forward") Fwd = Fwd.define(OneOf(None, C, TupleOf(Fwd), ListOf(Fwd), ConstDict(str, Fwd))) Fwd(C())
def test_basic_forward_type_resolution(self): f = Forward("f") T = TupleOf(f) f.define(int) self.assertEqual(T.__name__, "TupleOf(Int64)") self.assertEqual(f.get(), Int64)
def test_serializing_alternatives_in_loop(self): AT = Forward("AT") AT = AT.define(Alternative("AT", X={'x': int, 'y': float}, Y={'x': int, 'y': AT})) context = SerializationContext({'AT': AT}) self.serializeInLoop(lambda: AT, context=context) self.serializeInLoop(lambda: AT.Y, context=context) self.serializeInLoop(lambda: AT.X(x=10, y=20), context=context)
def test_serializing_anonymous_recursive_types(self): NT = Forward("NT") NT = NT.define(TupleOf(NT)) # right now we don't allow this. When we move to a more proper model for declarint # forward types, this should work better. with self.assertRaises(Exception): ping_pong(NT)
def test_cannot_create_cyclic_forwards(self): F0 = Forward("F0") F1 = Forward("F1") with self.assertRaisesRegex(Exception, "resolve forwards to concrete types only"): F1.define(F0) F0.define(int) F1.define(int)
def test_deep_forwards_work(self): X = Forward("X") X = X.define(TupleOf(TupleOf(TupleOf(TupleOf(OneOf(None, X)))))) str(X) anX = X( ((((None,),),),) ) anotherX = X( ((((anX,),),),) ) self.assertEqual(anotherX[0][0][0][0], anX)
def test_recursives_held_infinitely_throws(self): X = Forward("X") with self.assertRaisesRegex(Exception, "type-containment cycle"): X = X.define(NamedTuple(x=X)) with self.assertRaisesRegex(Exception, "type-containment cycle"): X = X.define(OneOf(None, X)) with self.assertRaisesRegex(Exception, "type-containment cycle"): X = X.define(Tuple(X))
def test_serialize_recursive_dict_more(self): D = Forward("D") D = D.define(Dict(str, OneOf(str, D))) x = SerializationContext({"D": D}) d = D() d["hi"] = "bye" d["recurses"] = d d2 = x.deserialize(x.serialize(d)) self.assertEqual(d2['recurses']['recurses']['hi'], 'bye')
def test_recursive_alternatives(self): X = Forward("X") X = X.define( Alternative( "X", A=dict(x=X, y=int), B=dict() ) ) anX = X.A(x=X.B(), y=21) self.assertEqual(anX.y, 21) self.assertTrue(anX.x.matches.B)
def test_recursive_dicts(self): D = Forward("D") D = D.define(Dict(int, OneOf(int, D))) dInst = D() dInst[10] = dInst dInst[20] = 20 self.assertEqual(dInst[10][10][10][20], 20) # stringifying it shouldn't blow up str(dInst) self.assertEqual(dInst, dInst[10])
def test_tuple_of_one_of(self): X = Forward("X") T = TupleOf(OneOf(None, X)) X = X.define(T) str(X) anX = X( (None,) ) self.assertTrue("Unresolved" not in str(X)) anotherX = X( (anX, anX) ) self.assertEqual(anotherX[0], anX)
def test_recursive_alternative(self): List = Forward("List") List = List.define(Alternative( "List", Node={'head': int, 'tail': List }, Leaf={}, unpack=lambda self: () if self.matches.Leaf else (self.head,) + self.tail.unpack() )) # ensure recursive implementation actually works lst = List.Leaf() for i in range(100): lst = List.Node(head=i, tail=lst) self.assertEqual(list(lst.unpack()), list(reversed(range(100))))
def test_mutually_recursive_classes(self): B0 = Forward("B") class A(Class): bvals = Member(TupleOf(B0)) class B(Class): avals = Member(TupleOf(A)) B0 = B0.define(B) a = A() b = B() a.bvals = (b,) b.avals = (a,) self.assertTrue(a.bvals[0].avals[0] == a)
def test_recursive_list(self): L = Forward("L") L = L.define(ListOf(OneOf(int, L))) listInst = L() listInst.append(10) listInst.append(listInst) self.assertEqual( serialize(L, listInst), BEGIN_COMPOUND(0) + ( VARINT(0) + unsignedVarint(0) + # the ID VARINT(0) + unsignedVarint(2) + # the size SINGLE(0) + VARINT(0) + signedVarint(10) + SINGLE(0) + SINGLE(1) + ( # a compound object encoding the second element of the one-of VARINT(0) + unsignedVarint(0) # the ID and nothing else )) + END_COMPOUND())
def test_forward_type_resolution_sequential(self): F0 = Forward("f0") T0 = TupleOf(F0) F1 = Forward("f1") T1 = TupleOf(F1) F1.define(T0) F0.define(int) self.assertEqual(T1.__name__, "TupleOf(TupleOf(Int64))")
def test_alternatives(self): X = Forward("X") X = X.define( Alternative("X", Left={ 'x': int, 'y': str }, Right={ 'x': X, 'val': int })) self.assertEqual(len(X.__typed_python_alternatives__), 2) Left, Right = X.__typed_python_alternatives__ self.assertEqual(Left.Index, 0) self.assertEqual(Right.Index, 1) self.assertEqual(Left.ElementType.ElementNames, ("x", "y")) self.assertEqual(Left.ElementType.ElementTypes, (Int64, String)) self.assertEqual(Right.ElementType.ElementNames, ('x', 'val')) self.assertEqual(Right.ElementType.ElementTypes, (X, Int64))
def test_recursive_oneof(self): OneOfTupleOfSelf = Forward("OneOfTupleOfSelf") OneOfTupleOfSelf = OneOfTupleOfSelf.define(OneOf(None, TupleOf(OneOfTupleOfSelf))) self.assertEqual(OneOfTupleOfSelf.__qualname__, "OneOfTupleOfSelf") self.assertEqual(OneOf(None, TupleOf(OneOfTupleOfSelf)).__qualname__, "OneOf(NoneType, TupleOf(OneOfTupleOfSelf))") TO = Forward("TO") TO = TO.define(TupleOf(OneOf(None, TO))) self.assertEqual(TO.__qualname__, "TO") self.assertIs(TO.ElementType.Types[1], TO) self.assertEqual(TO.ElementType.__qualname__, "OneOf(NoneType, TO)")
for k, v in c.element_types) + ")" if c.matches.Pointer: return "*" + str(c.value_type) if c.matches.Void: return "void" if c.matches.Array: return str(c.element_type) + "[" + str(c.count) + "]" assert False, type(c) def raising(e): raise e Type = Forward("Type") Type = Type.define( Alternative( "Type", Void={}, Float={'bits': int}, Int={ 'bits': int, 'signed': bool }, Struct={ 'element_types': TupleOf(Tuple(str, Type)), 'name': str }, Array={ 'element_type': Type,
def test_forward_types_not_instantiatable(self): F = Forward("int") F.define(int) with self.assertRaisesRegex(Exception, "Can't construct"): F(10)
# See the License for the specific language governing permissions and # limitations under the License. from typed_python import Function, OneOf, TupleOf, Forward import typed_python._types as _types from nativepython.runtime import Runtime import unittest def Compiled(f): f = Function(f) return Runtime.singleton().compile(f) # a simple recursive 'value' type for testing Value = Forward("Value") Value = Value.define( OneOf( # None, # bool, float, int, str, # bytes, # ConstDict(Value, Value), TupleOf(Value))) someValues = [ # None, # False,
def test_recursive_forwards(self): Value = Forward("Value") Value.define(OneOf( None, ConstDict(str, Value) ))
class Interior(Class): x = Member(int) y = Member(int) class Exterior(Class): x = Member(int) i = Member(Interior) iTup = Member(NamedTuple(x=Interior, y=Interior)) def __init__(self): self.i = Interior() ClassWithInit = Forward("ClassWithInit") @ClassWithInit.define class ClassWithInit(Class): x = Member(int) y = Member(float) z = Member(str) cwi = Member(ClassWithInit) def __init__(self): pass def __init__(self, x=1, cwi=None): # noqa: F811 self.x = x if cwi is not None: