def test_binary_compatibility_compatible_alternatives(self): ibc = _types.isBinaryCompatible A1 = Alternative("A1", X={'a': int}, Y={'b': float}) A2 = Alternative("A2", X={'a': int}, Y={'b': float}) self.assertTrue(ibc(A1.X, A2.X)) self.assertTrue(ibc(A1.Y, A2.Y)) self.assertFalse(ibc(A1.X, A2.Y)) self.assertFalse(ibc(A1.Y, A2.X))
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 List(T): return Alternative("List", Node={ "head": T, "tail": List(T) }, Empty={})
def test_alternatives(self): alt = Alternative( "Alt", child_ints={'x': int, 'y': int}, child_strings={'x': str, 'y': str} ) self.assertTrue(issubclass(alt.child_ints, alt)) self.assertTrue(issubclass(alt.child_strings, alt)) a = alt.child_ints(x=10,y=20) a2 = alt.child_ints(x=10,y=20) self.assertEqual(a,a2) self.assertTrue(isinstance(a, alt)) self.assertTrue(isinstance(a, alt.child_ints)) self.assertEqual(a.x, 10) self.assertEqual(a.y, 20) self.assertTrue(a.matches.child_ints) self.assertFalse(a.matches.child_strings) with self.assertRaisesRegex(AttributeError, "immutable"): a.x = 20
def makeAlternative(severalDicts): types = list( set( tuple( (k,typeFor(v)) for k,v in ntDict.items() ) for ntDict in severalDicts ) ) alt = Alternative("Alt", **{ "a_%s" % i: dict(types[i]) for i in range(len(types)) }) res = [] for thing in severalDicts: did = False for i in range(len(types)): try: res.append(getattr(alt,"a_%s" % i)(**thing)) did = True except Exception: pass if did: break assert len(res) == len(severalDicts) return res
def test_instantiating_invalid_forward(self): X = Alternative("X", A={'x': lambda: this_does_not_Exist}) with self.assertRaises(TypeError): X.A() this_does_not_exist = int #fixing it doesn't help with self.assertRaises(TypeError): X.A() #but a new type is OK. X = Alternative("X", A={'x': lambda: this_does_not_exist}) X.A()
def List(T): ListT = Forward("ListT") return ListT.define( Alternative("List", Node={ "head": T, "tail": ListT }, Empty={}))
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_alternative(self): A = Alternative("A", X=dict(a=int), Y=dict(b=float, c=float)) self.assertEqual(serialize(A, A.X(a=10)), SINGLE(0) + SINGLE(0) + VARINT(0) + signedVarint(10)) self.assertEqual( serialize(A, A.Y(b=10, c=20.2)), SINGLE(0) + BEGIN_COMPOUND(1) + BITS_64(0) + floatToBits(10) + BITS_64(1) + floatToBits(20.2) + END_COMPOUND())
def test_alternatives_add_operator(self): alt = Alternative( "Alt", child_ints={'x': int, 'y': int}, __add__=lambda l,r: (l,r) ) a = alt.child_ints(x=0,y=2) self.assertEqual(a+a,(a,a))
def test_alternatives_with_str_func(self): alt = Alternative( "Alt", x_0={'a':bytes}, f=lambda self: 1, __str__=lambda self: "not_your_usual_str" ) self.assertEqual(alt.x_0().f(), 1) self.assertEqual(str(alt.x_0()), "not_your_usual_str")
def test_extracted_alternatives_have_correct_type(self): Alt = Alternative( "Alt", A={}, B={} ) tOfAlt = TupleOf(Alt) a = Alt.A() aTup = tOfAlt((a,)) self.assertEqual(a, aTup[0]) self.assertTrue(type(a) is type(aTup[0]))
def test_construct_alternatives_with_positional_arguments(self): a = Alternative("A", HasOne = {'a': str}, HasTwo = {'a': str, 'b': str}) with self.assertRaises(TypeError): a.HasTwo("hi") self.assertEqual(a.HasOne("hi"), a.HasOne(a="hi")) hasOne = a.HasOne("hi") self.assertEqual(a.HasOne(hasOne), hasOne) with self.assertRaises(TypeError): a.HasOne(a.HasTwo(a='1',b='b'))
def test_empty_alternatives(self): a = Alternative( "Alt", A={}, B={} ) self.assertEqual(a.A(), a.A()) self.assertIsInstance(deserialize(a, serialize(a, a.A())), a.A) self.assertEqual(a.A(), deserialize(a, serialize(a, a.A()))) self.assertEqual(a.B(), a.B()) self.assertNotEqual(a.A(), a.B()) self.assertNotEqual(a.B(), a.A())
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_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_alternatives_perf(self): alt = Alternative( "Alt", child_ints={'x': int, 'y': int}, child_strings={'x': str, 'y': str} ) t0 = time.time() for i in range(1000000): a = alt.child_ints(x=10,y=20) a.matches.child_ints a.x elapsed = time.time() - t0 print("Took ", elapsed, " to do 1mm") self.check_expected_performance(elapsed, expected=2.0)
def test_refcounts_of_objects_across_boundary(self): class Object: pass _ = Object() A = Alternative("A", X={'x': int}, Y={'y': int}) for instance in [ TupleOf(int)((1, 2, 3)), ListOf(int)((1, 2, 3)), # Dict(int,int)({1:2,3:4}), ConstDict(int, int)({1: 2, 3: 4}), AClass(), # anObject, A.X(x=10) ]: self.refcountsTest(instance)
def test_serialize_primitive_compound_types(self): class A: pass B = Alternative("B", X={'a': A}) ts = SerializationContext({'A': A, 'B': B}) for t in [ ConstDict(int, float), NamedTuple(x=int, y=str), TupleOf(bool), Tuple(int, int, bool), OneOf(int, float), OneOf(1, 2, 3, "hi", b"goodbye"), TupleOf(NamedTuple(x=int)), TupleOf(object), TupleOf(A), TupleOf(B) ]: self.assertIs(ping_pong(t, ts), t)
def test_alternatives(self): X = Alternative("X", Left={ 'x': int, 'y': str }, Right={ 'x': lambda: X, 'val': int }) _types.resolveForwards(X) 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_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 callback(self, arg=None): self.callbackArgs.put(arg) self.is_released.get(timeout=1.0) def waitForCallback(self, timeout): return self.callbackArgs.get(timeout=timeout) def releaseCallback(self): self.is_released.put(True) expr = Alternative( "Expr", Constant={'value': int}, #Add = {'l': expr, 'r': expr}, #Sub = {'l': expr, 'r': expr}, #Mul = {'l': expr, 'r': expr} ) schema = Schema("test_schema") schema.expr = expr @schema.define class Root: obj = OneOf(None, schema.Object) k = int @schema.define
def execute(self, taskContext, subtaskResults): return TaskStatusResult.Finished(result=self.f(taskContext.db)) class FunctionTask(TaskExecutor): """A simple task that just runs a single function.""" def __init__(self, f): self.f = f def instantiate(self): return RunningFunctionTask(self.f) TaskStatusResult = Alternative( 'TaskStatusResult', Finished={'result': object}, Subtasks={'subtasks': ConstDict(str, TaskExecutor)}, SleepUntil={'wakeup_timestamp': float}) TaskResult = Alternative("TaskResult", Result={'result': object}, Error={'error': str}, Failure={}) @task_schema.define class Task: service = Indexed(service_schema.Service) service_and_finished = Index('service', 'finished') resourceScope = Indexed(OneOf(None, ResourceScope))
import queue import threading import logging import traceback import time from object_database.view import RevisionConflictException, DisconnectedException class Everything: """Singleton to mark subscription to everything in a slice.""" TransactionResult = Alternative("TransactionResult", Success={}, RevisionConflict={'key': str}, Disconnected={}) class VersionedBase: def _best_version_offset_for(self, version): i = len(self.version_numbers) - 1 while i >= 0: if self.version_numbers[i] <= version: return i i -= 1 return None def isEmpty(self):
def test_serialize_alternatives(self): A = Alternative("A", X={'a': int}, Y={'a': lambda: A}) ts = SerializationContext({'A': A}) self.assertIs(ping_pong(A.X, ts), A.X)
# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from object_database.algebraic_protocol import AlgebraicProtocol from typed_python import Alternative import asyncio import queue import ssl import unittest Message = Alternative("Message", Ping={}, Pong={}) class PingPongProtocol(AlgebraicProtocol): def __init__(self): AlgebraicProtocol.__init__(self, Message, Message) def messageReceived(self, m): if m.matches.Ping: self.sendMessage(Message.Pong()) class SendAndReturn(AlgebraicProtocol): def __init__(self, messageToSend, responseQueue): AlgebraicProtocol.__init__(self, Message, Message) self.messageToSend = messageToSend
Alternative( "Type", Void={}, Float={'bits': int}, Int={ 'bits': int, 'signed': bool }, Struct={ 'element_types': TupleOf(Tuple(str, Type)), 'name': str }, Array={ 'element_type': Type, 'count': int }, Function={ 'output': Type, 'args': TupleOf(Type), 'varargs': bool, 'can_throw': bool }, Pointer={'value_type': Type}, attr_ix=type_attr_ix, __str__=type_str, pointer=lambda self: Type.Pointer(value_type=self), zero=lambda self: Expression.Constant( Constant.Void() if self.matches.Void else Constant.Float(val=0.0, bits=self.bits) if self.matches.Float else Constant.Int( val=0, bits=self.bits, signed=self.signed) if self.matches.Int else Constant.Struct( elements=[(name, t.zero()) for name, t in self.element_types]) if self.matches.Struct else Constant.NullPointer(value_type=self. value_type) if self.matches.Pointer else raising( Exception("Can't make a zero value from %s" % self)))))
return _heartbeatInterval[0] ClientToServer = Alternative( "ClientToServer", TransactionData={ "writes": ConstDict(ObjectFieldId, OneOf(None, bytes)), "set_adds": ConstDict(IndexId, TupleOf(ObjectId)), "set_removes": ConstDict(IndexId, TupleOf(ObjectId)), "key_versions": TupleOf(ObjectFieldId), "index_versions": TupleOf(IndexId), "transaction_guid": int }, CompleteTransaction={ "as_of_version": int, "transaction_guid": int }, Heartbeat={}, DefineSchema={ 'name': str, 'definition': SchemaDefinition }, LoadLazyObject={ 'schema': str, 'typename': str, 'identity': ObjectId }, Subscribe={ 'schema': str, 'typename': OneOf(None, str), 'fieldname_and_value': OneOf(None, Tuple(str, IndexValue)), 'isLazy': bool # load values when we first request them, instead of blocking on all the data. }, Flush={'guid': int}, Authenticate={'token': str} ) ServerToClient = Alternative(
Display = lambda: Display Display = Alternative( "Display", Displays={ 'displays': TupleOf(Display), 'title': str }, Plot={ 'args': TupleOf(object), 'kwargs': ConstDict(str, object), 'title': str }, Object={ 'object': object, 'title': str }, # show an arbitrary python object (should be small - a class or module) Print={ 'str': str, 'title': str }, # show a message from the code. titled=lambda self, title: Display.Displays(displays=self.displays, title=title) if self.matches.Displays else Display.Object(object=self.object, title=title) if self.matches.Object else Display.Print(str=self.str, title=title) if self.matches.Print else None, __add__=lambda self, other: Display.Displays( displays=self.displays + other.displays, title=self.title if not other.title else other.title) if self.matches.Displays and other.matches.Displays else raising( TypeError, f"Can't add {type(self)} and {type(other)}"))
import threading import logging import traceback import time from object_database.view import DisconnectedException class Everything: """Singleton to mark subscription to everything in a slice.""" TransactionResult = Alternative( "TransactionResult", Success={}, RevisionConflict={'key': OneOf(str, ObjectFieldId, IndexId)}, Disconnected={} ) class DatabaseConnection: def __init__(self, channel, connectionMetadata=None): self._channel = channel self._transaction_callbacks = {} self._connectionMetadata = connectionMetadata or {} self._lock = threading.RLock() # transaction of what's in the KV store self._cur_transaction_num = 0