def nb_retrieve(self, value_id): """ Remote call from ``py.erl``: Retrieves a historical value by index. """ if value_id in self.history_: return Atom('ok'), self.history_[value_id] return Atom('error'), Atom('not_found')
def _decode_map(self, codec): """ Try a map #{1 => 2, ok => error} """ data = bytes([131, py_impl.TAG_MAP_EXT, 0, 0, 0, 2, py_impl.TAG_SMALL_INT, 1, py_impl.TAG_SMALL_INT, 2, py_impl.TAG_ATOM_EXT, 0, 2, 111, 107, py_impl.TAG_ATOM_EXT, 0, 5, 101, 114, 114, 111, 114]) (val, tail) = codec.binary_to_term(data, None) self.assertTrue(isinstance(val, dict)) self.assertEqual(val, {1: 2, Atom("ok"): Atom("error")}) self.assertEqual(tail, b'')
def resolve_arg(key_val): key, pyrlangval_tuple = key_val if isinstance(pyrlangval_tuple, tuple) \ and pyrlangval_tuple[0] == Atom("$pyrlangval"): return key, self._retrieve_value(pyrlangval_tuple) return key, pyrlangval_tuple
def _decode_tuple(self, codec): """ Try decode some tuple values """ data1 = bytes([131, py_impl.TAG_SMALL_TUPLE_EXT, 2, py_impl.TAG_SMALL_INT, 1, py_impl.TAG_ATOM_EXT, 0, 2, 111, 107]) (val1, tail1) = codec.binary_to_term(data1, None) self.assertEqual((1, Atom("ok")), val1) self.assertEqual(tail1, b'') data2 = bytes([131, py_impl.TAG_LARGE_TUPLE_EXT, 0, 0, 0, 2, py_impl.TAG_SMALL_INT, 1, py_impl.TAG_ATOM_EXT, 0, 2, 111, 107]) (val2, tail2) = codec.binary_to_term(data2, None) self.assertEqual((1, Atom("ok")), val2) self.assertEqual(tail2, b'') # Empty tuple data3 = bytes([131, py_impl.TAG_SMALL_TUPLE_EXT, 0]) (val3, tail3) = codec.binary_to_term(data3, None) self.assertEqual((), val3) self.assertEqual(tail3, b'')
def nb_batch(self, batch: List[tuple], param: Dict[Atom, any]): """ Take a remote call from Erlang to execute batch of Python calls. """ if not batch: return Atom("error"), Atom("batch_empty") call_imm = param[Atom("immediate")] for bitem in batch: call_path = bitem[Atom("path")] call_args = self._resolve_valuerefs_in_args(bitem[Atom("args")]) call_kwargs = self._resolve_valuerefs_in_kwargs( bitem[Atom("kwargs")]) call_ret = bitem[Atom("ret")] fn = self._resolve_path(call_path) result = fn(*call_args, **call_kwargs) last_result_name = self._store_result_as(result, call_ret) if call_imm: return Atom("value"), result return Atom("ok"), result.__class__.__name__, last_result_name
def _decode_list(self, codec): """ Try decode some list values """ data1 = bytes([131, py_impl.TAG_NIL_EXT]) (val1, tail1) = codec.binary_to_term(data1, None) self.assertEqual([], val1) self.assertEqual(tail1, b'') # Test data is [1, ok] data2 = bytes([131, py_impl.TAG_LIST_EXT, 0, 0, 0, 2, py_impl.TAG_SMALL_INT, 1, py_impl.TAG_ATOM_EXT, 0, 2, 111, 107, py_impl.TAG_NIL_EXT]) (val2, tail2) = codec.binary_to_term(data2, None) self.assertTrue(isinstance(val2, list), "Expected list, got: %s (%s)" % (val2.__class__.__name__, val2)) self.assertEqual(val2, [1, Atom("ok")]) self.assertEqual(tail2, b'')
def destroy(self): """ Closes incoming and outgoing connections and destroys the local node. """ self.is_exiting_ = True import copy all_processes = copy.copy(self.processes_) for p in all_processes.values(): p.exit(Atom('killed')) self.processes_.clear() self.reg_names_.clear() for dproto in self.dist_nodes_.values(): dproto.destroy() self.dist_nodes_.clear() self.dist_.destroy() del Node.all_nodes[self.node_name_] self.engine_.destroy()
def _resolve_path(self, p: List[str]) -> Callable: """ Imports p[0] and then follows the list p, by applying getattr() repeatedly. """ if isinstance(p, str): p = [p] # First element would be the import, or a stored value reference first_path_element = p[0] if isinstance(first_path_element, tuple) \ and first_path_element[0] == Atom("$pyrlangval"): # First element is {'$pyrlangval', X} - query the value val = self._retrieve_value(first_path_element) else: # First element is a string, import it val = __import__(as_str(first_path_element)) # Follow the elements in path, and getattr deeper for item in p[1:]: val = getattr(val, as_str(item)) return val
def nb_call(self, param: dict): """ Remote call from ``py.erl``: Calls function defined in ``args``, stores the result in history. :param param: contains ``path``: list of strings where first one is to be imported and remaining are used to find the function; ``args``: list of arguments for the callable; ``kwargs``; ``immediate``: will return the value instead of the value ref if this is ``True``, also will not update the history. :returns: Index for stored history value. """ call_path = param[Atom("path")] call_args = self._resolve_valuerefs_in_args(param[Atom("args")]) call_kwargs = self._resolve_valuerefs_in_kwargs(param[Atom("kwargs")]) call_imm = param[Atom("immediate")] fn = self._resolve_path(call_path) result = fn(*call_args, **call_kwargs) if call_imm: return Atom('value'), result index = self._store_result(result) return Atom('ok'), result.__class__.__name__, index
def _control_term_send(from_pid, dst): if isinstance(dst, Atom): return CONTROL_TERM_REG_SEND, from_pid, Atom(''), dst else: return CONTROL_TERM_SEND, Atom(''), dst
def __init__(self, node: Node) -> None: Process.__init__(self, node) node.register_name(self, Atom('rex')) self.traceback_depth_ = 5 """ This being non-zero enables formatting exception tracebacks with the
def test_b2t_library_equality_atoms(self): a = pycodec.term_to_binary(Atom("hello")) (b, _) = nativecodec.binary_to_term(a, None) self.assertEqual(Atom("hello"), b)
def _create_atom_atom(name: bytes, encoding: str) -> Atom: return Atom(text=name.decode(encoding))
def resolve_arg(pyrlangval_tuple): if isinstance(pyrlangval_tuple, tuple) \ and pyrlangval_tuple[0] == Atom("$pyrlangval"): return self._retrieve_value(pyrlangval_tuple) return pyrlangval_tuple
def is_auth(): return Atom('yes')
def __init__(self, node: Node) -> None: GenServer.__init__(self, node, accepted_calls=['is_auth']) node.register_name(self, Atom('net_kernel'))