From 5f0f2f90361a4c0a76478b288998595fc3ddebd2 Mon Sep 17 00:00:00 2001 From: Roger Gonzalez Date: Wed, 8 Apr 2020 10:38:14 -0300 Subject: Added my old emacs config --- .../lib/python3.7/site-packages/epc/__init__.py | 135 +++++++ .../epc/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3294 bytes .../epc/__pycache__/client.cpython-37.pyc | Bin 0 -> 3891 bytes .../epc/__pycache__/core.cpython-37.pyc | Bin 0 -> 3523 bytes .../epc/__pycache__/handler.cpython-37.pyc | Bin 0 -> 14478 bytes .../epc/__pycache__/py3compat.cpython-37.pyc | Bin 0 -> 1026 bytes .../epc/__pycache__/server.cpython-37.pyc | Bin 0 -> 7123 bytes .../epc/__pycache__/utils.cpython-37.pyc | Bin 0 -> 5043 bytes .../lib/python3.7/site-packages/epc/client.py | 139 +++++++ .../lib/python3.7/site-packages/epc/core.py | 131 +++++++ .../lib/python3.7/site-packages/epc/handler.py | 414 +++++++++++++++++++++ .../lib/python3.7/site-packages/epc/py3compat.py | 58 +++ .../lib/python3.7/site-packages/epc/server.py | 225 +++++++++++ .../python3.7/site-packages/epc/tests/__init__.py | 14 + .../epc/tests/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 138 bytes .../tests/__pycache__/test_client.cpython-37.pyc | Bin 0 -> 6285 bytes .../__pycache__/test_dispatcher.cpython-37.pyc | Bin 0 -> 2435 bytes .../tests/__pycache__/test_py2py.cpython-37.pyc | Bin 0 -> 8049 bytes .../tests/__pycache__/test_server.cpython-37.pyc | Bin 0 -> 14456 bytes .../tests/__pycache__/test_utils.cpython-37.pyc | Bin 0 -> 2322 bytes .../epc/tests/__pycache__/utils.cpython-37.pyc | Bin 0 -> 3361 bytes .../site-packages/epc/tests/test_client.py | 164 ++++++++ .../site-packages/epc/tests/test_dispatcher.py | 58 +++ .../site-packages/epc/tests/test_py2py.py | 205 ++++++++++ .../site-packages/epc/tests/test_server.py | 323 ++++++++++++++++ .../site-packages/epc/tests/test_utils.py | 63 ++++ .../lib/python3.7/site-packages/epc/tests/utils.py | 127 +++++++ .../lib/python3.7/site-packages/epc/utils.py | 155 ++++++++ 28 files changed, 2211 insertions(+) create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__init__.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/__init__.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/client.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/core.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/handler.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/py3compat.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/server.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/utils.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/client.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/core.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/handler.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/py3compat.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/server.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__init__.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/__init__.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_client.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_dispatcher.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_py2py.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_server.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_utils.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/utils.cpython-37.pyc create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_client.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_dispatcher.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_py2py.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_server.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_utils.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/utils.py create mode 100644 .emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/utils.py (limited to '.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc') diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__init__.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__init__.py new file mode 100644 index 00000000..3c5c2f41 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__init__.py @@ -0,0 +1,135 @@ +# [[[cog import cog; cog.outl('"""\n%s\n"""' % file('../README.rst').read())]]] +""" +EPC (RPC stack for Emacs Lisp) for Python +========================================= + +Links: + +* `Documentation `_ (at Read the Docs) +* `Repository `_ (at GitHub) +* `Issue tracker `_ (at GitHub) +* `PyPI `_ +* `Travis CI `_ |build-status| + +Other resources: + +* `kiwanami/emacs-epc `_ + (Client and server implementation in Emacs Lisp and Perl.) +* `tkf/emacs-jedi `_ + (Python completion for Emacs using EPC server.) + +.. |build-status| + image:: https://secure.travis-ci.org/tkf/python-epc.png + ?branch=master + :target: http://travis-ci.org/tkf/python-epc + :alt: Build Status + + +What is this? +------------- + +EPC is an RPC stack for Emacs Lisp and Python-EPC is its server side +and client side implementation in Python. Using Python-EPC, you can +easily call Emacs Lisp functions from Python and Python functions from +Emacs. For example, you can use Python GUI module to build widgets +for Emacs (see `examples/gtk/server.py`_ for example). + +Python-EPC is tested against Python 2.6, 2.7 and 3.2. + +Install +------- + +To install Python-EPC and its dependency sexpdata_, run the following +command.:: + + pip install epc + +.. _sexpdata: https://github.com/tkf/sexpdata + + +Usage +----- + +Save the following code as ``my-server.py``. +(You can find functionally the same code in `examples/echo/server.py`_):: + + from epc.server import EPCServer + + server = EPCServer(('localhost', 0)) + + @server.register_function + def echo(*a): + return a + + server.print_port() + server.serve_forever() + + +And then run the following code from Emacs. +This is a stripped version of `examples/echo/client.el`_ included in +Python-EPC repository_.:: + + (require 'epc) + + (defvar my-epc (epc:start-epc "python" '("my-server.py"))) + + (deferred:$ + (epc:call-deferred my-epc 'echo '(10)) + (deferred:nextc it + (lambda (x) (message "Return : %S" x)))) + + (message "Return : %S" (epc:call-sync my-epc 'echo '(10 40))) + + +.. _examples/echo/server.py: + https://github.com/tkf/python-epc/blob/master/examples/echo/server.py +.. _examples/echo/client.el: + https://github.com/tkf/python-epc/blob/master/examples/echo/client.el + +If you have carton_ installed, you can run the above sample by +simply typing the following commands:: + + make elpa # install EPC in a separated environment + make run-sample # run examples/echo/client.el + +.. _carton: https://github.com/rejeep/carton + + +For example of bidirectional communication and integration with GTK, +see `examples/gtk/server.py`_. You can run this example by:: + + make elpa + make run-gtk-sample # run examples/gtk/client.el + +.. _examples/gtk/server.py: + https://github.com/tkf/python-epc/blob/master/examples/gtk/server.py + + +License +------- + +Python-EPC is licensed under GPL v3. +See COPYING for details. + +""" +# [[[end]]] + +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +__version__ = '0.0.5' +__author__ = 'Takafumi Arakaki' +__license__ = 'GNU General Public License v3 (GPLv3)' diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/__init__.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000..1871b6f9 Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/__init__.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/client.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/client.cpython-37.pyc new file mode 100644 index 00000000..56e8e0b5 Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/client.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/core.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/core.cpython-37.pyc new file mode 100644 index 00000000..dbbf284d Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/core.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/handler.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/handler.cpython-37.pyc new file mode 100644 index 00000000..4d1411a9 Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/handler.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/py3compat.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/py3compat.cpython-37.pyc new file mode 100644 index 00000000..9763e96d Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/py3compat.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/server.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/server.cpython-37.pyc new file mode 100644 index 00000000..95e3525a Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/server.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/utils.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/utils.cpython-37.pyc new file mode 100644 index 00000000..87e63b40 Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/__pycache__/utils.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/client.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/client.py new file mode 100644 index 00000000..f24a7cd9 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/client.py @@ -0,0 +1,139 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from .py3compat import Queue +from .utils import ThreadedIterator, newthread +from .core import EPCCore +from .handler import ThreadingEPCHandler + + +class EPCClientHandler(ThreadingEPCHandler): + + # In BaseRequestHandler, everything happen in `.__init__()`. + # Let's defer it to `.start()`. + + def __init__(self, *args): + self._args = args + self._ready = Queue.Queue() + + def start(self): + ThreadingEPCHandler.__init__(self, *self._args) + + def setup(self): + ThreadingEPCHandler.setup(self) + self._ready.put(True) + + def wait_until_ready(self): + self._ready.get() + + def _recv(self): + self._recv_iter = ThreadedIterator(ThreadingEPCHandler._recv(self)) + return self._recv_iter + + +class EPCClient(EPCCore): + + """ + EPC client class to call remote functions and serve Python functions. + + >>> client = EPCClient() + >>> client.connect(('localhost', 9999)) #doctest: +SKIP + >>> client.call_sync('echo', [111, 222, 333]) #doctest: +SKIP + [111, 222, 333] + + To serve Python functions, you can use :meth:`register_function`. + + >>> client.register_function(str.upper) + + + :meth:`register_function` can be used as a decorator. + + >>> @client.register_function + ... def add(x, y): + ... return x + y + + Also, you can initialize client and connect to the server by one line. + + >>> client = EPCClient(('localhost', 9999)) #doctest: +SKIP + + .. method:: call + + Alias of :meth:`epc.server.EPCHandler.call`. + + .. method:: call_sync + + Alias of :meth:`epc.server.EPCHandler.call_sync`. + + .. method:: methods + + Alias of :meth:`epc.server.EPCHandler.methods`. + + .. method:: methods_sync + + Alias of :meth:`epc.server.EPCHandler.methods_sync`. + + """ + + thread_daemon = True + + def __init__(self, socket_or_address=None, + debugger=None, log_traceback=False): + if socket_or_address is not None: + self.connect(socket_or_address) + EPCCore.__init__(self, debugger, log_traceback) + + def connect(self, socket_or_address): + """ + Connect to server and start serving registered functions. + + :type socket_or_address: tuple or socket object + :arg socket_or_address: A ``(host, port)`` pair to be passed + to `socket.create_connection`, or + a socket object. + + """ + if isinstance(socket_or_address, tuple): + import socket + self.socket = socket.create_connection(socket_or_address) + else: + self.socket = socket_or_address + + # This is what BaseServer.finish_request does: + address = None # it is not used, so leave it empty + self.handler = EPCClientHandler(self.socket, address, self) + + self.call = self.handler.call + self.call_sync = self.handler.call_sync + self.methods = self.handler.methods + self.methods_sync = self.handler.methods_sync + + self.handler_thread = newthread(self, target=self.handler.start) + self.handler_thread.daemon = self.thread_daemon + self.handler_thread.start() + self.handler.wait_until_ready() + + def close(self): + """Close connection.""" + try: + self.handler._recv_iter.stop() + except AttributeError: + # Do not fail to close even if the client is never used. + pass + + def _ignore(*_): + """"Do nothing method for `EPCHandler`.""" + add_client = _ignore + remove_client = _ignore diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/core.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/core.py new file mode 100644 index 00000000..5157f77d --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/core.py @@ -0,0 +1,131 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import logging +from .py3compat import SimpleXMLRPCServer + + +def _get_logger(): + """ + Generate a logger with a stream handler. + """ + logger = logging.getLogger('epc') + hndlr = logging.StreamHandler() + hndlr.setLevel(logging.INFO) + hndlr.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) + logger.addHandler(hndlr) + return logger +_logger = _get_logger() + + +class EPCDispatcher: + + # This class will be mixed with `SocketServer.TCPServer`, + # which is an old style class. + + # see also: SimpleXMLRPCServer.SimpleXMLRPCDispatcher + + def __init__(self): + self.funcs = {} + self.instance = None + + def register_instance(self, instance, allow_dotted_names=False): + """ + Register an instance to respond to EPC requests. + + :type instance: object + :arg instance: + An object with methods to provide to peer. If this + instance has `_get_method` method, EPC method name + resolution can be done by this method. + + :type allow_dotted_names: bool + :arg allow_dotted_names: + If it is true, method names containing dots are supported. + They are resolved using `getattr` for each part of the + name as long as it does not start with '_'. + + Unlike :meth:`register_function`, only one instance can + be registered. + + """ + self.instance = instance + self.allow_dotted_names = allow_dotted_names + + def register_function(self, function, name=None): + """ + Register function to be called from EPC client. + + :type function: callable + :arg function: Function to publish. + :type name: str + :arg name: Name by which function is published. + + This method returns the given `function` as-is, so that you + can use it as a decorator. + + """ + if name is None: + name = function.__name__ + self.funcs[name] = function + return function + + def get_method(self, name): + """ + Get registered method callend `name`. + """ + try: + return self.funcs[name] + except KeyError: + try: + return self.instance._get_method(name) + except AttributeError: + return SimpleXMLRPCServer.resolve_dotted_attribute( + self.instance, name, self.allow_dotted_names) + + +class EPCCore(EPCDispatcher): + + """ + Core methods shared by `EPCServer` and `EPCClient`. + """ + + logger = _logger + + def __init__(self, debugger, log_traceback): + EPCDispatcher.__init__(self) + self.set_debugger(debugger) + self.log_traceback = log_traceback + + def set_debugger(self, debugger): + """ + Set debugger to run when an error occurs in published method. + + You can also set debugger by passing `debugger` argument to + the class constructor. + + :type debugger: {'pdb', 'ipdb', None} + :arg debugger: type of debugger. + + """ + if debugger == 'pdb': + import pdb + self.debugger = pdb + elif debugger == 'ipdb': + import ipdb + self.debugger = ipdb + else: + self.debugger = debugger diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/handler.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/handler.py new file mode 100644 index 00000000..3e67ea00 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/handler.py @@ -0,0 +1,414 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import sys +import itertools +import threading + +from sexpdata import loads, dumps, Symbol, String + +from .py3compat import SocketServer, Queue +from .utils import autolog, LockingDict, newthread, callwith + + +class BaseRemoteError(Exception): + """ + All exceptions from remote method are derived from this class. + """ + + +class CallerUnknown(BaseRemoteError): + """ + Error raised in remote method, but caller of the method is unknown. + """ + + +class EPCError(BaseRemoteError): + """ + Error returned by `epc-error` protocol. + """ + + +class ReturnError(BaseRemoteError): + """ + Error returned by `return-error` protocol. + """ + + +class EPCErrorCallerUnknown(CallerUnknown, EPCError): + """ + Same as :class:`EPCError`, but caller is unknown. + """ + + +class ReturnErrorCallerUnknown(CallerUnknown, ReturnError): + """ + Same as :class:`ReturnError`, but caller is unknown. + """ + + +class EPCClosed(Exception): + """ + Trying to send to a closed socket. + """ + + +def encode_string(string): + data = string.encode('utf-8') + datalen = '{0:06x}'.format(len(data) + 1).encode() + return _JOIN_BYTES([datalen, data, _NEWLINE_BYTE]) +_JOIN_BYTES = ''.encode().join +_NEWLINE_BYTE = '\n'.encode() + + +def encode_object(obj, **kwds): + return encode_string(dumps(obj, **kwds)) + + +def encode_message(name, *args, **kwds): + return encode_object([Symbol(name)] + list(args), **kwds) + + +def unpack_message(bytes): + data = loads(bytes.decode('utf-8')) + return (data[0].value(), data[1], data[2:]) + + +def itermessage(read): + while True: + head = read(6) + if not head: + return + length = int(head, 16) + data = read(length) + if len(data) < length: + raise ValueError('need {0}-length data; got {1}' + .format(length, len(data))) + yield data + + +class BlockingCallback(object): + + def __init__(self): + self.queue = q = Queue.Queue() + self.callback = lambda x: q.put(('return', x)) + self.errback = lambda x: q.put(('error', x)) + self.cbs = {'callback': self.callback, 'errback': self.errback} + + def result(self, timeout): + (rtype, reply) = self.queue.get(timeout=timeout) + if rtype == 'return': + return reply + else: + raise reply + + +class EPCCallManager: + + Dict = LockingDict # FIXME: make it configurable from server class. + """ + Dictionary class used to store callbacks. + """ + + def __init__(self): + self.callbacks = self.Dict() + counter = itertools.count(1) + self.get_uid = callwith(threading.Lock())(lambda: next(counter)) + # Wrapping by threading.Lock is useless for non-threading + # handler. Probably it is better to make it optional. + + def call(self, handler, name, args=[], callback=None, errback=None): + uid = self.get_uid() + self.callbacks[uid] = (callback, errback) + handler._send('call', uid, Symbol(name), args) + + def methods(self, handler, callback=None, errback=None): + uid = self.get_uid() + self.callbacks[uid] = (callback, errback) + handler._send('methods', uid) + + def handle_return(self, uid, reply): + try: + (callback, _) = self.callbacks.pop(uid) + except (KeyError, TypeError): + raise CallerUnknown(reply) + if callback is not None: + callback(reply) + + def _handle_error_reply(self, uid, reply, eclass, notfound): + try: + (_, errback) = self.callbacks.pop(uid) + except (KeyError, TypeError): + raise notfound(reply) + error = eclass(reply) + if errback is None: + raise error + else: + errback(error) + + def handle_return_error(self, uid, reply): + self._handle_error_reply(uid, reply, ReturnError, + ReturnErrorCallerUnknown) + + def handle_epc_error(self, uid, reply): + self._handle_error_reply(uid, reply, EPCError, + EPCErrorCallerUnknown) + + +class EPCHandler(SocketServer.StreamRequestHandler): + + # These attribute are defined in `SocketServer.BaseRequestHandler` + # self.server : an instance of `EPCServer` + # self.request : + # self.client_address + + # These attribute are defined in `SocketServer.StreamRequestHandler` + # self.connection : = self.request + # self.rfile : stream from client + # self.wfile : stream to client + + @property + def logger(self): + return self.server.logger + + @autolog('debug') + def setup(self): + SocketServer.StreamRequestHandler.setup(self) + self.callmanager = EPCCallManager() + self.server.add_client(self) + + @autolog('debug') + def finish(self): + try: + SocketServer.StreamRequestHandler.finish(self) + finally: + self.server.remove_client(self) + + def _rfile_read_safely(self, size): + try: + return self.rfile.read(size) + except (AttributeError, ValueError): + if self.rfile.closed: + # Calling read on closed socket raises + # AttributeError in 2.x and ValueError in 3.x. + # http://bugs.python.org/issue9177 + raise StopIteration + else: + raise # if not, just re-raise it. + + def _recv(self): + self.logger.debug('receiving...') + for data in itermessage(self._rfile_read_safely): + self.logger.debug( + 'received: length = %r; data = %r', len(data), data) + yield data + self.logger.debug('receiving...') + + @autolog('debug') + def _send(self, *args): + string = encode_message(*args) + try: + self.wfile.write(string) + except (AttributeError, ValueError): + # See also: :meth:`_rfile_read_safely` + raise EPCClosed + + @autolog('debug') + def handle(self): + for sexp in self._recv(): + self._handle(sexp) + + @autolog('debug') + def _handle(self, sexp): + uid = undefined = [] # default: nil + try: + (name, uid, args) = unpack_message(sexp) + pyname = name.replace('-', '_') + getattr(self, '_validate_{0}'.format(pyname))(uid, args) + handler = getattr(self, '_handle_{0}'.format(pyname)) + reply = handler(uid, *args) + if reply is not None: + self._send(*reply) + except Exception as err: + if self.handle_error(err): + return + if self.server.debugger or self.server.log_traceback: + exc_info = sys.exc_info() + self.logger.error('Unexpected error', exc_info=exc_info) + if self.server.debugger: + self.server.debugger.post_mortem(exc_info[2]) + name = 'epc-error' if uid is undefined else 'return-error' + self._send(name, uid, repr(err)) + + @autolog('debug') + def _handle_call(self, uid, meth, args): + # See: `epc:handler-called-method` + name = meth.value() + try: + func = self.server.get_method(name) + except AttributeError: + return ['epc-error', uid, + "EPC-ERROR: No such method : {0}".format(name)] + return ['return', uid, func(*args)] + + def _handle_methods(self, uid): + return ['return', uid, [ + (Symbol(name), [], String(func.__doc__ or "")) + # FIXNE: implement arg-specs + for (name, func) + in self.server.funcs.items()]] + + def _handle_return(self, uid, reply): + self.callmanager.handle_return(uid, reply) + + def _handle_return_error(self, uid, reply=None, *_): + self.callmanager.handle_return_error(uid, reply) + + def _handle_epc_error(self, uid, reply=None, *_): + self.callmanager.handle_epc_error(uid, reply) + + _epc_error_template = \ + "(%s %d ...): Got %s arguments in the reply: %r" + + def _validate_call(self, uid, args, num_expect=2, name='call'): + len_args = len(args) + if len_args == num_expect: + return + elif len_args < num_expect: + message = 'Not enough arguments {0!r}'.format(args) + else: + message = 'Too many arguments {0!r}'.format(args) + self._send("epc-error", uid, message) + raise EPCError('({0} {1} ...): {2}'.format(name, uid, message)) + + def _validate_methods(self, uid, args): + self._validate_call(uid, args, 0, 'methods') + + def _validate_return(self, uid, args): + len_args = len(args) + error = lambda x: self._epc_error_template % ('return', uid, x, args) + if len_args == 0: + message = error('not enough') + elif len_args > 1: + message = error('too many') + else: + return + self.logger.error(message) + self._handle_epc_error(uid, message) + raise EPCError(message) + + def _validate_return_error(self, uid, args): + self._log_extra_argument_error('return-error', uid, args) + + def _validate_epc_error(self, uid, args): + self._log_extra_argument_error('epc-error', uid, args) + + def _log_extra_argument_error(self, name, uid, args): + if len(args) > 1: + self.logger.error(self._epc_error_template, + 'return-error', uid, 'too many', args) + + def handle_error(self, err): + """ + Handle error which is not handled by errback. + + :type err: Exception + :arg err: An error not handled by other mechanisms. + :rtype: boolean + + Return True from this function means that error is properly + handled, so the error is not sent to client. Do not confuse + this with :meth:`SocketServer.BaseServer.handle_error`. This + method is for handling error for each client, not for entire + server. Default implementation logs the error and returns + True if the error is coming from remote [#]_ or returns False + otherwise. Therefore, only the error occurs in this handler + class is sent to remote. + + .. [#] More specifically, it returns True if `err` is an + instance of :class:`BaseRemoteError` or :class:`EPCClosed`. + + """ + self.logger.error(repr(err)) + if isinstance(err, (BaseRemoteError, EPCClosed)): + # BaseRemoteError: do not send error back + # EPCClosed: no exception from thread + return True + + def call(self, name, *args, **kwds): + """ + Call method connected to this handler. + + :type name: str + :arg name: Method name to call. + :type args: list + :arg args: Arguments for remote method to call. + :type callback: callable + :arg callback: A function to be called with returned value of + the remote method. + :type errback: callable + :arg errback: A function to be called with an error occurred + in the remote method. It is either an instance + of :class:`ReturnError` or :class:`EPCError`. + + """ + self.callmanager.call(self, name, *args, **kwds) + + def methods(self, *args, **kwds): + """ + Request info of callable remote methods. + + Arguments for :meth:`call` except for `name` can be applied to + this function too. + + """ + self.callmanager.methods(self, *args, **kwds) + + @staticmethod + def _blocking_request(call, timeout, *args): + bc = BlockingCallback() + call(*args, **bc.cbs) + return bc.result(timeout=timeout) + + def call_sync(self, name, args, timeout=None): + """ + Blocking version of :meth:`call`. + + :type name: str + :arg name: Remote function name to call. + :type args: list + :arg args: Arguments passed to the remote function. + :type timeout: int or None + :arg timeout: Timeout in second. None means no timeout. + + If the called remote function raise an exception, this method + raise an exception. If you give `timeout`, this method may + raise an `Empty` exception. + + """ + return self._blocking_request(self.call, timeout, name, args) + + def methods_sync(self, timeout=None): + """ + Blocking version of :meth:`methods`. See also :meth:`call_sync`. + """ + return self._blocking_request(self.methods, timeout) + + +class ThreadingEPCHandler(EPCHandler): + + def _handle(self, sexp): + newthread(self, target=EPCHandler._handle, args=(self, sexp)).start() diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/py3compat.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/py3compat.py new file mode 100644 index 00000000..ba5d3c47 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/py3compat.py @@ -0,0 +1,58 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import sys +PY3 = (sys.version_info[0] >= 3) + +try: + import SocketServer +except: + import socketserver as SocketServer + +try: + import SimpleXMLRPCServer +except: + import xmlrpc.server as SimpleXMLRPCServer + +try: + import Queue +except: + import queue as Queue + + +try: + from contextlib import nested +except ImportError: + from contextlib import contextmanager + + @contextmanager + def nested(*managers): + if managers: + with managers[0] as ctx: + with nested(*managers[1:]) as rest: + yield (ctx,) + rest + else: + yield () + + +if PY3: + utf8 = lambda s: s +else: + utf8 = lambda s: s.decode('utf-8') + +utf8.__doc__ = """ +Decode a raw string into unicode object. Do nothing in Python 3. +""" diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/server.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/server.py new file mode 100644 index 00000000..555d3cd8 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/server.py @@ -0,0 +1,225 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import sys +import logging + +from .py3compat import SocketServer +from .utils import autolog, deprecated +from .core import EPCCore +from .handler import EPCHandler, ThreadingEPCHandler + + +@deprecated +def setuplogfile(logger=None, filename='python-epc.log'): + if logger is None: + from .core import _logger as logger + ch = logging.FileHandler(filename=filename, mode='w') + ch.setLevel(logging.DEBUG) + logger.addHandler(ch) + + +class EPCClientManager: + + # This class will be mixed with `SocketServer.TCPServer`, + # which is an old style class. + + def __init__(self): + self.clients = [] + """ + A list of :class:`EPCHandler` object for connected clients. + """ + + def add_client(self, handler): + self.clients.append(handler) + self.handle_client_connect(handler) + + def remove_client(self, handler): + self.clients.remove(handler) + self.handle_client_disconnect(handler) + + def handle_client_connect(self, handler): + """ + Handler which is called with a newly connected `client`. + + :type handler: :class:`EPCHandler` + :arg handler: Object for handling request from the client. + + Default implementation does nothing. + + """ + + def handle_client_disconnect(self, handler): + """ + Handler which is called with a disconnected `client`. + + :type handler: :class:`EPCHandler` + :arg handler: Object for handling request from the client. + + Default implementation does nothing. + + """ + + +class EPCServer(SocketServer.TCPServer, EPCClientManager, + EPCCore): + + """ + A server class to publish functions and call functions via EPC protocol. + + To publish Python functions, all you need is + :meth:`register_function`, + :meth:`print_port` and + :meth:`serve_forever() `. + + >>> server = EPCServer(('localhost', 0)) + >>> def echo(*a): + ... return a + >>> server.register_function(echo) #doctest: +ELLIPSIS + + >>> server.print_port() #doctest: +SKIP + 9999 + >>> server.serve_forever() #doctest: +SKIP + + To call client's method, use :attr:`clients ` + attribute to get client handler and use its :meth:`EPCHandler.call` and + :meth:`EPCHandler.methods` methods to communicate with connected client. + + >>> handler = server.clients[0] #doctest: +SKIP + >>> def callback(reply): + ... print(reply) + >>> handler.call('method_name', ['arg-1', 'arg-2', 'arg-3'], + ... callback) #doctest: +SKIP + + See :class:`SocketServer.TCPServer` and :class:`SocketServer.BaseServer` + for other usable methods. + + """ + + def __init__(self, server_address, + RequestHandlerClass=EPCHandler, + bind_and_activate=True, + debugger=None, log_traceback=False): + # `BaseServer` (super class of `SocketServer`) will set + # `RequestHandlerClass` to the attribute `self.RequestHandlerClass`. + # This class is initialize in `BaseServer.finish_request` by + # `self.RequestHandlerClass(request, client_address, self)`. + SocketServer.TCPServer.__init__( + self, server_address, RequestHandlerClass, bind_and_activate) + EPCClientManager.__init__(self) + EPCCore.__init__(self, debugger, log_traceback) + self.logger.debug('-' * 75) + self.logger.debug( + "EPCServer is initialized: server_address = %r", + self.server_address) + + @autolog('debug') + def handle_error(self, request, client_address): + self.logger.error('handle_error: trying to get traceback.format_exc') + try: + import traceback + self.logger.error('handle_error: \n%s', traceback.format_exc()) + except: + self.logger.error('handle_error: OOPS') + + def print_port(self, stream=sys.stdout): + """ + Print port this EPC server runs on. + + As Emacs client reads port number from STDOUT, you need to + call this just before calling :meth:`serve_forever`. + + :type stream: text stream + :arg stream: A stream object to write port on. + Default is :data:`sys.stdout`. + + """ + stream.write(str(self.server_address[1])) + stream.write("\n") + stream.flush() + + +class ThreadingEPCServer(SocketServer.ThreadingMixIn, EPCServer): + + """ + Class :class:`EPCServer` mixed with :class:`SocketServer.ThreadingMixIn`. + + Use this class when combining EPCServer with other Python module + which has event loop, such as GUI modules. For example, see + `examples/gtk/server.py`_ for how to use this class with GTK + + .. _examples/gtk/server.py: + https://github.com/tkf/python-epc/blob/master/examples/gtk/server.py + + """ + + def __init__(self, *args, **kwds): + kwds.update(RequestHandlerClass=ThreadingEPCHandler) + EPCServer.__init__(self, *args, **kwds) + + +def main(args=None): + """ + Quick CLI to serve Python functions in a module. + + Example usage:: + + python -m epc.server --allow-dotted-names os + + Note that only the functions which gets and returns simple + built-in types (str, int, float, list, tuple, dict) works. + + """ + import argparse + from textwrap import dedent + parser = argparse.ArgumentParser( + formatter_class=type('EPCHelpFormatter', + (argparse.ArgumentDefaultsHelpFormatter, + argparse.RawDescriptionHelpFormatter), + {}), + description=dedent(main.__doc__)) + parser.add_argument( + 'module', help='Serve python functions in this module.') + parser.add_argument( + '--address', default='localhost', + help='server address') + parser.add_argument( + '--port', default=0, type=int, + help='server port. 0 means to pick up random port.') + parser.add_argument( + '--allow-dotted-names', default=False, action='store_true') + parser.add_argument( + '--pdb', dest='debugger', const='pdb', action='store_const', + help='start pdb when error occurs.') + parser.add_argument( + '--ipdb', dest='debugger', const='ipdb', action='store_const', + help='start ipdb when error occurs.') + parser.add_argument( + '--log-traceback', action='store_true', default=False) + ns = parser.parse_args(args) + + server = EPCServer((ns.address, ns.port), + debugger=ns.debugger, + log_traceback=ns.log_traceback) + server.register_instance( + __import__(ns.module), + allow_dotted_names=ns.allow_dotted_names) + server.print_port() + server.serve_forever() + + +if __name__ == '__main__': + main() diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__init__.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__init__.py new file mode 100644 index 00000000..3c5738f7 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__init__.py @@ -0,0 +1,14 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/__init__.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 00000000..42b1ba1f Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/__init__.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_client.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_client.cpython-37.pyc new file mode 100644 index 00000000..fa0a49cf Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_client.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_dispatcher.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_dispatcher.cpython-37.pyc new file mode 100644 index 00000000..4001af86 Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_dispatcher.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_py2py.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_py2py.cpython-37.pyc new file mode 100644 index 00000000..8ebe0a5d Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_py2py.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_server.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_server.cpython-37.pyc new file mode 100644 index 00000000..ae514606 Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_server.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_utils.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_utils.cpython-37.pyc new file mode 100644 index 00000000..594b5237 Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_utils.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/utils.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/utils.cpython-37.pyc new file mode 100644 index 00000000..67f39acf Binary files /dev/null and b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/utils.cpython-37.pyc differ diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_client.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_client.py new file mode 100644 index 00000000..278111df --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_client.py @@ -0,0 +1,164 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import io + +from sexpdata import Symbol + +from ..client import EPCClient +from ..handler import encode_message, unpack_message, BlockingCallback, \ + ReturnError, EPCError +from ..py3compat import Queue +from .utils import BaseTestCase + + +class FakeFile(object): + pass + + +class FakeSocket(object): + + def __init__(self): + self._queue = Queue.Queue() + self._buffer = io.BytesIO() + self.sent_message = Queue.Queue() + self._alive = True + + def makefile(self, mode, *_): + ff = FakeFile() + ff.closed = False + ff.close = lambda: None + ff.flush = lambda: None + if 'r' in mode: + ff.read = self.recv + return ff + elif 'w' in mode: + ff.write = self.sendall + return ff + + def append(self, byte): + self._queue.put(byte) + + def _pull(self): + byte = self._queue.get() + pos = self._buffer.tell() + self._buffer.write(byte) + self._buffer.seek(pos) + + def recv(self, bufsize): + while True: + if not self._alive: + return '' + got = self._buffer.read(bufsize) + if got: + return got + # Do not go to the next loop until some byte is appended + # to the queue: + self._pull() + + def sendall(self, string): + self.sent_message.put(string) + + def close(self): + self._alive = False + self.append(''.encode('ascii')) + + +class TestClient(BaseTestCase): + + def setUp(self): + self.fsock = FakeSocket() + self.next_reply = [] + self.client = EPCClient(self.fsock) + + @self.client.register_function + def echo(*a): + """Return argument unchanged.""" + return a + + def tearDown(self): + self.client.socket.close() # connection is closed by server + + def set_next_reply(self, *args): + self.next_reply.append(encode_message(*args)) + + def request(self, name, *args): + bc = BlockingCallback() + getattr(self.client, name)(*args, **bc.cbs) + self.fsock.append(self.next_reply.pop(0)) # reply comes after call! + return bc.result(timeout=self.timeout) + + def sent_message(self): + raw = self.fsock.sent_message.get(timeout=self.timeout) + (name, uid, rest) = unpack_message(raw[6:]) + if name == 'call': + rest[0] = rest[0].value() + return [name, uid] + rest + + def check_sent_message(self, name, uid, args): + sent = self.sent_message() + self.assertEqual(sent, [name, uid] + list(args)) + + def check_return(self, desired_return, name, *args): + uid = 1 + self.set_next_reply('return', uid, desired_return) + got = self.request(name, *args) + self.assertEqual(got, desired_return) + self.check_sent_message(name, uid, args) + + def test_call_return(self): + self.check_return('some value', 'call', 'dummy', [1, 2, 3]) + + def test_methods_return(self): + self.check_return([[Symbol('dummy'), [], "document"]], 'methods') + + def check_return_error(self, reply_name, name, *args): + uid = 1 + reply = 'error value' + eclass = ReturnError if reply_name == 'return-error' else EPCError + error = eclass(reply) + self.set_next_reply(reply_name, uid, reply) + try: + self.request(name, *args) + assert False, 'self.client.{0}({1}) should raise an error' \ + .format(name, args) + except Exception as got: + self.assertIsInstance(got, type(error)) + self.assertEqual(got.args, error.args) + self.check_sent_message(name, uid, args) + + def test_call_return_error(self): + self.check_return_error('return-error', 'call', 'dummy', [1, 2, 3]) + + def test_call_epc_error(self): + self.check_return_error('epc-error', 'call', 'dummy', [1, 2, 3]) + + def test_methods_return_error(self): + self.check_return_error('return-error', 'methods') + + def test_methods_epc_error(self): + self.check_return_error('epc-error', 'methods') + + def test_echo(self): + uid = 1 + self.fsock.append(encode_message('call', uid, Symbol('echo'), [55])) + self.check_sent_message('return', uid, [[55]]) + + +class TestClientClosedByClient(TestClient): + + def tearDown(self): + self.client.close() diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_dispatcher.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_dispatcher.py new file mode 100644 index 00000000..cbce618b --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_dispatcher.py @@ -0,0 +1,58 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from ..core import EPCDispatcher +from .utils import BaseTestCase + + +class Dummy(object): + pass + + +class TestEPCDispatcher(BaseTestCase): + + def setUp(self): + self.dispatcher = EPCDispatcher() + + def test_register_module(self): + import os + self.dispatcher.register_instance(os) + self.assertIs(self.dispatcher.get_method('chmod'), os.chmod) + + def test_register_module_with_dotted_names(self): + import os + self.dispatcher.register_instance(os, allow_dotted_names=True) + self.assertIs(self.dispatcher.get_method('path.join'), os.path.join) + + def test_error_on_private_method_access(self): + obj = Dummy() + obj._private_method = lambda: None + obj.sub = Dummy() + obj.sub._private_attribute = Dummy() + obj.sub._private_attribute.some_method = lambda: None + self.dispatcher.register_instance(obj, allow_dotted_names=True) + self.assertRaises(AttributeError, self.dispatcher.get_method, + '_private_method') + self.assertRaises(AttributeError, self.dispatcher.get_method, + 'obj.sub._private_attribute.some_method') + + def test_instance_get_method(self): + always_me = lambda: None + obj = Dummy() + obj._get_method = lambda _: always_me + self.dispatcher.register_instance(obj) + self.assertIs(self.dispatcher.get_method('x'), always_me) + self.assertIs(self.dispatcher.get_method('y'), always_me) diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_py2py.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_py2py.py new file mode 100644 index 00000000..88d2ca72 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_py2py.py @@ -0,0 +1,205 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import os +import nose + +from ..client import EPCClient +from ..server import ThreadingEPCServer +from ..handler import ReturnError +from ..utils import newthread, callwith +from ..py3compat import Queue +from .utils import BaseTestCase, logging_to_stdout + + +def next_fib(x, fib): + if x < 2: + return x + return fib(x - 1) + fib(x - 2) + + +def fib(x): + return next_fib(x, fib) + + +class ThreadingPy2Py(object): + + """ + A class to setup connected EPC server and client in one process. + + This class is useful to use as a mix-in for test cases. + + """ + + def setup_connection(self, **kwds): + self.server = ThreadingEPCServer(('localhost', 0), **kwds) + self.server.daemon_threads = True + self.server_thread = newthread(self, target=self.server.serve_forever) + self.server_thread.start() + + self.client_queue = q = Queue.Queue() + self.server.handle_client_connect = q.put + + self.client = EPCClient(self.server.server_address, **kwds) + + def teardown_connection(self): + self.client.close() + self.server.shutdown() + self.server.server_close() + + def wait_until_client_is_connected(self): + if not self.client_ready: + self.client_queue.get(timeout=1) + self.client_ready = True + + client_ready = False + + +class TestEPCPy2Py(ThreadingPy2Py, BaseTestCase): + + def setUp(self): + ThreadingEPCServer.allow_reuse_address = True + self.setup_connection() + + @self.client.register_function + @self.server.register_function + def echo(*a): + """Return argument unchanged.""" + return a + + @self.client.register_function + @self.server.register_function + def bad_method(*_): + """This is a bad method. Don't call!""" + raise ValueError("This is a bad method!") + + @self.server.register_function + def ping_server(x): + return self.server.clients[0].call_sync('pong_client', [x]) + + @self.client.register_function + def pong_client(x): + return self.client.call_sync('echo', [x]) + + @self.client.register_function + def ping_client(x): + return self.client.call_sync('pong_server', [x]) + + @self.server.register_function + def pong_server(x): + return self.server.clients[0].call_sync('echo', [x]) + + @self.server.register_function + def fib_server(x): + c = self.server.clients[0].call_sync + return next_fib(x, lambda x: c('fib_client', [x])) + + @self.client.register_function + def fib_client(x): + c = self.client.call_sync + return next_fib(x, lambda x: c('fib_server', [x])) + + def tearDown(self): + self.teardown_connection() + + def assert_call_return(self, call, method, args, reply, **kwds): + timeout = kwds.get('timeout', self.timeout) + self.assertEqual(call(method, args, timeout=timeout), reply) + + def assert_client_return(self, method, args, reply, **kwds): + self.assert_call_return(self.client.call_sync, + method, args, reply, **kwds) + + def assert_server_return(self, method, args, reply, **kwds): + self.wait_until_client_is_connected() + self.assert_call_return(self.server.clients[0].call_sync, + method, args, reply, **kwds) + + def check_bad_method(self, call_sync): + cm = logging_to_stdout(self.server.logger) + call_sync = callwith(cm)(call_sync) + self.assertRaises(ReturnError, call_sync, 'bad_method', [55]) + + def test_client_calls_server_echo(self): + self.assert_client_return('echo', [55], [55]) + + def test_client_calls_server_bad_method(self): + self.check_bad_method(self.client.call_sync) + + def test_server_calls_client_echo(self): + self.assert_server_return('echo', [55], [55]) + + def test_server_calls_client_bad_method(self): + self.wait_until_client_is_connected() + self.check_bad_method(self.server.clients[0].call_sync) + + max_message_limit = int('f' * 6, 16) + 1 # 16MB + large_data_limit = max_message_limit \ + / float(os.getenv('PYEPC_TEST_LARGE_DATA_DISCOUNT', '128')) + large_data_limit = int(large_data_limit) + """ + Environment variable PYEPC_TEST_LARGE_DATA_DISCOUNT controls + how large "large data" must be. Default is ``2 ** 7`` times + smaller than the maximum message length (16 MB). Setting + it to 1 must *not* fail. However, it takes long time to finish + the test (typically 100 sec when I tried). Setting this value + to less than one (e.g., 0.9) *must* fail the tests. + """ + + def check_large_data(self, assert_return): + margin = 100 # for parenthesis, "call", uid, etc. + data = "x" * (self.large_data_limit - margin) + timeout = self.timeout * 100 + assert_return('echo', [data], [data], timeout=timeout) + + def test_client_sends_large_data(self): + self.check_large_data(self.assert_client_return) + + def test_server_sends_large_data(self): + self.check_large_data(self.assert_server_return) + + def test_client_ping_pong(self): + self.assert_client_return('ping_server', [55], [55]) + + def test_server_ping_pong(self): + self.assert_server_return('ping_client', [55], [55]) + + def test_client_close_should_not_fail_even_if_not_used(self): + pass + + fibonacci = list(map(fib, range(12))) + fibonacci_min = 2 + """ + The Fibonacci test must succeeds at least until this index. + """ + + def check_fib(self, assert_return, method): + try: + for (i, f) in enumerate(self.fibonacci): + assert_return(method, [i], f) + except Queue.Empty: + if i > self.fibonacci_min: + raise nose.SkipTest( + "Test for {0} fails at {1} (> {2}), but it's OK." + .format(method, i, self.fibonacci_min)) + else: + raise # not OK + + def test_client_fib(self): + self.check_fib(self.assert_client_return, 'fib_server') + + def test_server_fib(self): + self.check_fib(self.assert_server_return, 'fib_client') diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_server.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_server.py new file mode 100644 index 00000000..e44a796e --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_server.py @@ -0,0 +1,323 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import socket + +from sexpdata import Symbol, loads + +from ..server import ThreadingEPCServer +from ..utils import newthread +from ..handler import encode_string, encode_object, BlockingCallback, \ + ReturnError, EPCError, ReturnErrorCallerUnknown, EPCErrorCallerUnknown, \ + CallerUnknown +from ..py3compat import utf8, Queue, nested +from .utils import mockedattr, logging_to_stdout, CaptureStdIO, BaseTestCase, \ + streamio + + +class TestEPCServerMisc(BaseTestCase): + + """ + Test that can be done without client. + """ + + def setUp(self): + # See: http://stackoverflow.com/questions/7720953 + ThreadingEPCServer.allow_reuse_address = True + self.server = ThreadingEPCServer(('localhost', 0)) + self.server_thread = newthread(self, target=self.server.serve_forever) + self.server_thread.start() + + def tearDown(self): + self.server.shutdown() + self.server.server_close() + + def test_print_port(self): + stream = streamio() + self.server.print_port(stream) + self.assertEqual(stream.getvalue(), + '{0}\n'.format(self.server.server_address[1])) + + +class BaseEPCServerTestCase(BaseTestCase): + + def setUp(self): + # See: http://stackoverflow.com/questions/7720953 + ThreadingEPCServer.allow_reuse_address = True + self.server = ThreadingEPCServer(('localhost', 0)) + self.server_thread = newthread(self, target=self.server.serve_forever) + self.server_thread.start() + + def echo(*a): + """Return argument unchanged.""" + return a + + def bad_method(*_): + """This is a bad method. Don't call!""" + raise self.error_to_throw + self.error_to_throw = ValueError("This is a bad method!") + + self.server.register_function(echo) + self.server.register_function(bad_method) + + self.client = socket.create_connection(self.server.server_address) + self.client.settimeout(self.timeout) + + def tearDown(self): + self.client.shutdown(socket.SHUT_RDWR) + self.client.close() + self.server.shutdown() + self.server.server_close() + + def receive_message(self): + result = self.client.recv(1024) + self.assertEqual(int(result[:6], 16), len(result[6:])) + return loads(result[6:].decode()) # skip the length part + + def client_send(self, string): + self.client.send(encode_string(string)) + + def check_echo(self): + self.client_send('(call 1 echo (55))') + result = self.client.recv(1024) + self.assertEqual(encode_string('(return 1 (55))'), result) + + +class TestEPCServerRequestHandling(BaseEPCServerTestCase): + + """ + Test that EPCServer handles request from client properly. + """ + + def test_echo(self): + self.check_echo() + + def test_error_in_method(self): + with logging_to_stdout(self.server.logger): + self.client_send('(call 2 bad_method nil)') + result = self.client.recv(1024) + expected = encode_object([ + Symbol('return-error'), 2, repr(self.error_to_throw)]) + self.assertEqual(result, expected) + + def test_no_such_method(self): + with logging_to_stdout(self.server.logger): + self.client_send('(call 3 no_such_method nil)') + reply = self.receive_message() + self.assertEqual(reply[0], Symbol('epc-error')) + self.assertEqual(reply[1], 3) + assert 'No such method' in reply[2] + + def test_methods(self): + self.client_send('(methods 4)') + reply = self.receive_message() + self.assertEqual(reply[0], Symbol('return')) + self.assertEqual(reply[1], 4) + method = dict((m[0].value(), m[1:]) for m in reply[2]) + self.assertEqual(set(method), set(['echo', 'bad_method'])) + + actual_docs = dict( + (n, doc) for (n, (_, doc)) in method.items()) + desired_docs = dict( + (n, f.__doc__) for (n, f) in self.server.funcs.items()) + self.assertEqual(actual_docs, desired_docs) + + def test_unicode_message(self): + s = "日本語能力!!ソハンカク" + self.client_send(utf8('(call 1 echo ("{0}"))'.format(s))) + result = self.client.recv(1024) + self.assertEqual(encode_string(utf8('(return 1 ("{0}"))'.format(s))), + result) + + def test_invalid_sexp(self): + with logging_to_stdout(self.server.logger): + self.client_send('(((invalid sexp!') + reply = self.receive_message() + self.assertEqual(reply[0].value(), Symbol('epc-error').value()) + self.assertEqual(reply[1], []) # uid + assert 'Not enough closing brackets.' in reply[2] + + def check_caller_unkown(self, message, eclass, eargs): + self.check_echo() # to establish connection to client + called_with = Queue.Queue() + with nested(mockedattr(self.server.clients[0], + 'handle_error', called_with.put), + logging_to_stdout(self.server.logger)): + self.client_send(message) + error = called_with.get(True, 1) + self.assertIsInstance(error, eclass) + self.assertEqual(error.args, eargs) + + def test_return_caller_unkown(self): + self.check_caller_unkown( + '(return 0 ("some" "value"))', # uid=0 is always unkown + CallerUnknown, (['some', 'value'],)) + + def test_return_error_caller_unkown(self): + self.check_caller_unkown( + '(return-error nil "message")', + ReturnErrorCallerUnknown, ('message',)) + + def test_epc_error_caller_unkown(self): + self.check_caller_unkown( + '(epc-error nil "message")', + EPCErrorCallerUnknown, ('message',)) + + def check_invalid_call(self, make_call): + + # These are not necessary for the actual test, but rather + # to make sure that the server stays in the context of + # `logging_to_stdout` until the error is handled. See + # `called_with.get` below. + def handle_error(err): + self.assertTrue(orig_handle_error(err)) + called_with.put(err) + return True + self.check_echo() # to fetch handler + handler = self.server.clients[0] + orig_handle_error = handler.handle_error + called_with = Queue.Queue() + + # Here comes the actual test: + uid = 1 + with nested(logging_to_stdout(self.server.logger), + mockedattr(handler, 'handle_error', handle_error)): + self.client_send(make_call(uid)) + reply = self.receive_message() + called_with.get(timeout=1) # wait until the error got handled + self.assertEqual(reply[0], Symbol('epc-error')) + self.assertEqual(reply[1], uid) + + def test_invalid_call_not_enough_arguments(self): + self.check_invalid_call('(call {0} echo)'.format) + + def test_invalid_call_too_many_arguments(self): + self.check_invalid_call( + '(call {0} echo "value" "extra" "value")'.format) + + def test_invalid_methods_too_many_arguments(self): + self.check_invalid_call('(methods {0} "extra value")'.format) + + def test_log_traceback(self): + stdio = CaptureStdIO() + with nested(stdio, mockedattr(self.server, 'log_traceback', True)): + self.test_error_in_method() + log = stdio.read_stdout() + self.assertIn('ValueError: This is a bad method!', log) + self.assertIn('raise self.error_to_throw', log) + + +class TestEPCServerCallClient(BaseEPCServerTestCase): + + def setUp(self): + super(TestEPCServerCallClient, self).setUp() + self.check_echo() # to start connection, client must send something + self.handler = self.server.clients[0] + + self.callback_called_with = Queue.Queue() + self.callback = self.callback_called_with.put + + self.errback_called_with = Queue.Queue() + self.errback = self.errback_called_with.put + + def check_call_client_dummy_method(self): + (call, uid, meth, args) = self.receive_message() + self.assertIsInstance(uid, int) + self.assertEqual([call, uid, meth, args], + [Symbol('call'), uid, Symbol('dummy'), [55]]) + return uid + + def test_call_client_dummy_method(self): + self.handler.call('dummy', [55], self.callback, self.errback) + uid = self.check_call_client_dummy_method() + self.client_send('(return {0} 123)'.format(uid)) + reply = self.callback_called_with.get(True, 1) + self.assertEqual(reply, 123) + + def test_call_client_methods_info(self): + self.handler.methods(self.callback) + (methods, uid) = self.receive_message() + self.assertEqual(methods.value(), 'methods') + self.client_send('(return {0} ((dummy () "")))'.format(uid)) + reply = self.callback_called_with.get(True, 1) + self.assertEqual(reply, [[Symbol('dummy'), [], ""]]) + + def client_send_error(self, ename, uid, message): + self.client_send('({0} {1} "{2}")'.format(ename, uid, message)) + + def check_call_client_error(self, ename, eclass, message=utf8("message")): + self.handler.call('dummy', [55], self.callback, self.errback) + uid = self.check_call_client_dummy_method() + self.client_send_error(ename, uid, message) + reply = self.errback_called_with.get(True, 1) + self.assertIsInstance(reply, eclass) + self.assertEqual(reply.args, (message,)) + + def test_call_client_return_error(self): + self.check_call_client_error('return-error', ReturnError) + + def test_call_client_epc_error(self): + self.check_call_client_error('epc-error', EPCError) + + def check_dont_send_error_back(self, ename, eclass, + message=utf8("message")): + self.handler.call('dummy', [55]) # no callbacks! + uid = self.check_call_client_dummy_method() + with logging_to_stdout(self.server.logger): + self.client_send_error(ename, uid, message) + try: + result = self.client.recv(1024) + self.assertEqual(result, '') # nothing goes to client + except socket.timeout: + pass + + def test_dont_send_return_error_back(self): + self.check_dont_send_error_back('return-error', ReturnError) + + def test_dont_send_epc_error_back(self): + self.check_dont_send_error_back('epc-error', EPCError) + + def check_invalid_reply(self, make_reply, should_raise=EPCError): + bc = BlockingCallback() + self.handler.call('dummy', [55], **bc.cbs) + uid = self.check_call_client_dummy_method() + with logging_to_stdout(self.server.logger): + self.client_send(make_reply(uid)) + self.assertRaises(should_raise, bc.result, timeout=self.timeout) + + def test_invalid_return_not_enough_arguments(self): + self.check_invalid_reply('(return {0})'.format) + + def test_invalid_return_too_many_arguments(self): + self.check_invalid_reply( + '(return {0} "value" "extra" "value")'.format) + + def test_invalid_return_error_not_enough_arguments(self): + self.check_invalid_reply('(return-error {0})'.format, ReturnError) + + def test_invalid_return_error_too_many_arguments(self): + self.check_invalid_reply( + '(return-error {0} "value" "extra" "value")'.format, + ReturnError) + + def test_invalid_epc_error_not_enough_arguments(self): + self.check_invalid_reply('(epc-error {0})'.format) + + def test_invalid_epc_error_too_many_arguments(self): + self.check_invalid_reply( + '(epc-error {0} "value" "extra" "value")'.format) diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_utils.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_utils.py new file mode 100644 index 00000000..a485f0ca --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_utils.py @@ -0,0 +1,63 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from ..utils import ThreadedIterator, LockingDict + +from .utils import BaseTestCase + + +class TestThreadedIterator(BaseTestCase): + + def check_identity(self, iterable): + lst = list(iterable) + self.assertEqual(list(ThreadedIterator(lst)), lst) + + def test_empty(self): + self.check_identity([]) + + def test_range_1(self): + self.check_identity(range(1)) + + def test_range_7(self): + self.check_identity(range(7)) + + +class TestLockingDict(BaseTestCase): + + def setUp(self): + self.ld = LockingDict() + + def check_set_items(self, items): + for (k, v) in items: + self.ld[k] = v + self.assertEqual(dict(**self.ld), dict(items)) + + def test_simple_set_items(self): + self.check_set_items(dict(a=1, b=2, c=3).items()) + + def test_simple_del_items(self): + self.test_simple_set_items() + ld = self.ld + del ld['a'] + del ld['b'] + self.assertEqual(dict(**self.ld), dict(c=3)) + + def test_simple_pop_items(self): + self.test_simple_set_items() + ld = self.ld + self.assertEqual(ld.pop('a'), 1) + self.assertEqual(ld.pop('b'), 2) + self.assertEqual(dict(**self.ld), dict(c=3)) diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/utils.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/utils.py new file mode 100644 index 00000000..c6815c64 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/utils.py @@ -0,0 +1,127 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import os +import sys +import functools +import io + +try: + import unittest + unittest.TestCase.assertIs +except AttributeError: + import unittest2 as unittest +from contextlib import contextmanager + +from ..py3compat import Queue, PY3 +from ..utils import newthread + + +@contextmanager +def mockedattr(object, name, replace): + """ + Mock `object.name` attribute using `replace`. + """ + original = getattr(object, name) + try: + setattr(object, name, replace) + yield + finally: + setattr(object, name, original) + + +def logging_to_stdout(logger): + # it assumes that 0-th hander is the only one stream handler... + return mockedattr(logger.handlers[0], 'stream', sys.stdout) + + +def streamio(): + """ + Return `io.StringIO` for Python 3, otherwise `io.BytesIO`. + """ + if PY3: + return io.StringIO() + else: + return io.BytesIO() + + +class CaptureStdIO(object): + + def __enter__(self): + self._orig_stdin = sys.stdin + self._orig_stdout = sys.stdout + self._orig_stderr = sys.stderr + + self.stdin = sys.stdin = streamio() + self.stdout = sys.stdout = streamio() + self.stderr = sys.stderr = streamio() + return self + + def __exit__(self, exc_type, exc_value, traceback): + sys.stdin = self._orig_stdin + sys.stdout = self._orig_stdout + sys.stderr = self._orig_stderr + + def read_stdout(self): + self.stdout.seek(0) + return self.stdout.read() + + def read_stderr(self): + self.stderr.seek(0) + return self.stderr.read() + + +class BaseTestCase(unittest.TestCase): + + TRAVIS = os.getenv('TRAVIS') + + if TRAVIS: + timeout = 10 + else: + timeout = 1 + + +def skip(reason): + from nose import SkipTest + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwds): + raise SkipTest("Skipping {0} because: {1}" + .format(func.__name__, reason)) + return wrapper + return decorator + + +def post_mortem_in_thread(traceback): + """ + `pdb.post_mortem` that can be used in a daemon thread. + + Put the following in the `except`-block:: + + import sys + from epc.tests.utils import post_mortem_in_thread + exc_info = sys.exc_info() + post_mortem_in_thread(exc_info[2]) + + """ + import pdb + blocker = Queue.Queue() + thread = newthread(target=blocker.get) + thread.daemon = False + thread.start() + pdb.post_mortem(traceback) + blocker.put(None) diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/utils.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/utils.py new file mode 100644 index 00000000..ec3570c4 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/utils.py @@ -0,0 +1,155 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import logging +import itertools +import functools +import threading +import warnings + +from .py3compat import Queue + + +def func_call_as_str(name, *args, **kwds): + """ + Return arguments and keyword arguments as formatted string + + >>> func_call_as_str('f', 1, 2, a=1) + 'f(1, 2, a=1)' + + """ + return '{0}({1})'.format( + name, + ', '.join(itertools.chain( + map('{0!r}'.format, args), + map('{0[0]!s}={0[1]!r}'.format, sorted(kwds.items()))))) + + +def autolog(level): + if isinstance(level, str): + level = getattr(logging, level.upper()) + + def wrapper(method): + @functools.wraps(method) + def new_method(self, *args, **kwds): + funcname = ".".join([self.__class__.__name__, method.__name__]) + self.logger.log(level, "(AutoLog) Called: %s", + func_call_as_str(funcname, *args, **kwds)) + ret = method(self, *args, **kwds) + self.logger.log(level, "(AutoLog) Returns: %s(...) = %r", + funcname, ret) + return ret + return new_method + return wrapper + + +def deprecated(func): + """ + Decorator for marking function as deprecated + """ + @functools.wraps(func) + def wrapper(*args, **kwargs): + warnings.warn( + '{0} is deprecated.'.format(func.__name__), + category=DeprecationWarning, + stacklevel=2, + ) + return func(*args, **kwargs) + return wrapper + + +def newname(template): + global _counter + _counter = _counter + 1 + return template.format(_counter) +_counter = 0 + + +def newthread(template="EPCThread-{0}", **kwds): + """ + Instantiate :class:`threading.Thread` with an appropriate name. + """ + if not isinstance(template, str): + template = '{0}.{1}-{{0}}'.format(template.__module__, + template.__class__.__name__) + return threading.Thread( + name=newname(template), **kwds) + + +class ThreadedIterator(object): + + def __init__(self, iterable): + self._original_iterable = iterable + self.queue = Queue.Queue() + self.thread = newthread(self, target=self._target) + self.thread.daemon = True + self._sentinel = object() + self.thread.start() + + def _target(self): + for result in self._original_iterable: + self.queue.put(result) + self.stop() + + def stop(self): + self.queue.put(self._sentinel) + + def __iter__(self): + return self + + def __next__(self): + got = self.queue.get() + if got is self._sentinel: + raise StopIteration + return got + next = __next__ # for PY2 + + +def callwith(context_manager): + """ + A decorator to wrap execution of function with a context manager. + """ + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwds): + with context_manager: + return func(*args, **kwds) + return wrapper + return decorator + + +def _define_thread_safe_methods(methodnames, lockname): + def define(cls, name): + def wrapper(self, *args, **kwds): + with getattr(self, lockname): + return method(self, *args, **kwds) + method = getattr(cls, name) + setattr(cls, name, wrapper) + + def decorator(cls): + for name in methodnames: + define(cls, name) + return cls + return decorator + + +@_define_thread_safe_methods( + ['__getitem__', '__setitem__', '__delitem__', 'pop'], '_lock') +class LockingDict(dict): + + def __init__(self, *args, **kwds): + super(LockingDict, self).__init__(*args, **kwds) + self._lock = threading.Lock() -- cgit v1.2.3