Пример #1
0
def decorate(func, caller, extras=()):
    """
    decorate(func, caller) decorates a function using a caller.
    If the caller is a generator function, the resulting function
    will be a generator function.
    """
    evaldict = dict(_call_=caller, _func_=func)
    es = ''
    for i, extra in enumerate(extras):
        ex = '_e%d_' % i
        evaldict[ex] = extra
        es += ex + ', '

    if '3.5' <= sys.version < '3.6':
        # with Python 3.5 isgeneratorfunction returns True for all coroutines
        # however we know that it is NOT possible to have a generator
        # coroutine in python 3.5: PEP525 was not there yet
        generatorcaller = isgeneratorfunction(
            caller) and not iscoroutinefunction(caller)
    else:
        generatorcaller = isgeneratorfunction(caller)
    if generatorcaller:
        fun = FunctionMaker.create(
            func, "for res in _call_(_func_, %s%%(shortsignature)s):\n"
                  "    yield res" % es, evaldict, __wrapped__=func)
    else:
        fun = FunctionMaker.create(
            func, "return _call_(_func_, %s%%(shortsignature)s)" % es,
            evaldict, __wrapped__=func)
    if hasattr(func, '__qualname__'):
        fun.__qualname__ = func.__qualname__
    return fun
Пример #2
0
    def test_coroutine_type_when_patched(self):
        @asyncio.coroutine
        def a_coroutine():
            pass

        a_patched_coroutine = patch_is_patched()(a_coroutine)

        self.assertEqual(asyncio.iscoroutinefunction(a_patched_coroutine),
                         asyncio.iscoroutinefunction(a_coroutine))
        self.assertEqual(inspect.isgeneratorfunction(a_patched_coroutine),
                         inspect.isgeneratorfunction(a_coroutine))
        coro = a_coroutine()
        patched_coro = a_patched_coroutine()
        try:
            self.assertEqual(asyncio.iscoroutine(patched_coro),
                             asyncio.iscoroutine(coro))
        finally:
            run_coroutine(coro)
            run_coroutine(patched_coro)

        if not _using_await:
            return

        a_coroutine = _using_await.transform(a_coroutine)
        a_patched_coroutine = patch_is_patched()(a_coroutine)
        self.assertEqual(asyncio.iscoroutinefunction(a_patched_coroutine),
                         asyncio.iscoroutinefunction(a_coroutine))
        coro = a_coroutine()
        patched_coro = a_patched_coroutine()
        try:
            self.assertEqual(asyncio.iscoroutine(patched_coro),
                             asyncio.iscoroutine(coro))
        finally:
            run_coroutine(coro)
            run_coroutine(patched_coro)
Пример #3
0
def main():
    print isgeneratorfunction(numList) 
    for num in numList(10):
        print num

    for content in read_file('../README.md'):
        print content
Пример #4
0
 def openFile(self, filePath, cursorPosition = None, focus = True, mainWindow = None, useTasks = True):
     """Open a editor in current window"""
     filePath = self.fileManager.normcase(filePath)
     
     if self.fileManager.isOpen(filePath):
         mainWindow, editor = self.findEditorForFile(filePath)
         if editor is not None:
             mainWindow.setCurrentEditor(editor)
             if isinstance(cursorPosition, tuple):
                 editor.setCursorPosition(cursorPosition)
     elif self.fileManager.exists(filePath):
         mainWindow = mainWindow or self.mainWindow
         editor = self.createEditorInstance(filePath, mainWindow)
         def on_editorReady(mainWindow, editor, cursorPosition, focus):
             def editorReady(openResult):
                 if isinstance(cursorPosition, tuple):
                     editor.setCursorPosition(cursorPosition)
                 mainWindow.tryCloseEmptyEditor()
                 mainWindow.addEditor(editor, focus)
             return editorReady
         if useTasks and inspect.isgeneratorfunction(editor.open):
             task = self.scheduler.newTask( editor.open(filePath) )
             task.done.connect( on_editorReady(mainWindow, editor, cursorPosition, focus) )
         elif inspect.isgeneratorfunction(editor.open):
             on_editorReady(mainWindow, editor, cursorPosition, focus)(list(editor.open(filePath)))
         else:
             on_editorReady(mainWindow, editor, cursorPosition, focus)(editor.open(filePath))
Пример #5
0
    def object(self, obj_id):

        if isinstance(obj_id, six.string_types):

            if obj_id.startswith('st__'):  # a string literal
                return obj_id[4:]

            if obj_id in self._objs:
                return self._objs[obj_id]

            if obj_id not in self._rec:
                raise GlueSerializeError("Unrecognized object %s" % obj_id)

            if obj_id in self._working:
                raise GlueSerializeError("Circular Reference detected: %s" % obj_id)

            self._working.add(obj_id)
            rec = self._rec[obj_id]

        elif isinstance(obj_id, literals) or isinstance(obj_id, (tuple, list)):
            return obj_id
        else:
            rec = obj_id

        func = self._dispatch(rec)

        try:

            obj = func(rec, self)

            if hasattr(obj, '__setgluestate_callback__'):
                self._callbacks.append(obj.__setgluestate_callback__)

            # loader functions might yield the constructed value,
            # and then futher populate it. This deals with circular
            # dependencies.
            if isgeneratorfunction(func):
                gen, obj = obj, next(obj)  # get the partially-constructed value...

            if isinstance(obj_id, six.string_types):  # ... add it to the registry ...
                self._objs[obj_id] = obj
                self._working.remove(obj_id)

            if isgeneratorfunction(func):
                for _ in gen:  # ... and finish constructing it
                    pass

        finally:

            # If anything in the try: block above fails, we need to remove the
            # obj_id from te list of IDs we are currently working on, as we
            # may want to try again (this happens when using the callbacks below)

            if isinstance(obj_id, six.string_types) and obj_id in self._working:
                self._working.remove(obj_id)

        self._try_callbacks()

        return obj
Пример #6
0
    def parameter_wrapper(target):

        # Annotated Class
        if inspect.isclass(target):
            webmodules = []
            for name, method in inspect.getmembers(target(), inspect.ismethod):
                # Checking whether the method is exposed to called from
                # web in the Class
                try:
                    method_webname = method.__webname__
                except:
                    if name == '__call__':
                        method_webname = ""
                    else:
                        continue

                invoker = ClassMethodInvoker(name, target)
                if len(method_webname) == 0:
                    url = parameter
                else:
                    url = parameter + method_webname if parameter.endswith("/") \
                        else parameter + "/" + method_webname

                webmodules.append({
                    "url": url,
                    "func": invoker,
                    "handler": method,
                    "type": "file" if inspect.isgeneratorfunction(method) else "json",
                    "arguments": utils.get_signature_details(method),
                    "desc": target.__doc__
                })
            target.__webmodules__ = webmodules

        # Annotated function
        elif inspect.isfunction(target):

            target.__webmodule__ = {
                "url": parameter,
                "func": FunctionInvoker(target),
                "handler": target,
                "type": "file" if inspect.isgeneratorfunction(target) else "json",
                "arguments": utils.get_signature_details(target),
                "desc": target.__doc__
            }
        else:
            raise Exception("Not implemented to support " + str(type(target)))

        return target
Пример #7
0
    def pre_process_extensions(self, extensions, request, action_args):
        # List of callables for post-processing extensions
        post = []

        for ext in extensions:
            if inspect.isgeneratorfunction(ext):
                response = None

                # If it's a generator function, the part before the
                # yield is the preprocessing stage
                try:
                    with ResourceExceptionHandler():
                        gen = ext(req=request, **action_args)
                        response = gen.next()
                except Fault as ex:
                    response = ex

                # We had a response...
                if response:
                    return response, []

                # No response, queue up generator for post-processing
                post.append(gen)
            else:
                # Regular functions only perform post-processing
                post.append(ext)

        # Run post-processing in the reverse order
        return None, reversed(post)
Пример #8
0
def wizcmd(func):
    """
    Public decorator to define a wizard command function.
    It adds a privilege check wrapper and checks the signature.
    Can be used by the user that is writing story code.
    """
    func.enable_notify_action = False   # none of the wizard commands should be used with notify_action
    func.is_tale_command_func = True

    # NOTE: this code is VERY similar to the internal @wizcmd decorator in cmds/wizard.py
    # If changes are made, make sure to update both occurrences
    @functools.wraps(func)
    def executewizcommand(player, parsed, ctx):
        if "wizard" not in player.privileges:
            raise errors.SecurityViolation("Wizard privilege required for verb " + parsed.verb)
        return func(player, parsed, ctx)

    if inspect.isgeneratorfunction(func):
        func.is_generator = True   # contains async yields
    argspec = inspect.getargspec(func)
    if argspec.args == ["player", "parsed", "ctx"] and argspec.varargs is None and argspec.keywords is None and argspec.defaults is None:
        func.__doc__ = util.format_docstring(func.__doc__)
        return executewizcommand
    else:
        raise SyntaxError("invalid wizcmd function signature for: " + func.__name__)
Пример #9
0
    def dispatch_item_single(self, item):
        """
            Given a JSON item received from socket, determine its type and 
            process the message.
        """
        assert type(item) is dict
        item.setdefault("id", None)

        if "method" in item:
            method, args, kw = self._extract_params(item)
            obj = self._find_object(method, args, kw)
            if obj is None:
                return
            fn = self._find_method(obj, method, args, kw)
            try:
                if inspect.isgeneratorfunction(fn):
                    for response in fn(*args, **kw):
                        self._send_response(item, response)
                elif callable(fn):
                    self._send_response(item, fn(*args, **kw))
                elif fn:
                    self._send_error(item, fn)
            except ServerError as exc:
                self._send_error(item, str(exc))
            except Exception:
                err = self._format_exception(obj, method, args, kw, sys.exc_info())
                self._send_error(item, err)
        elif "result" in item:
            assert item["id"] in self._requests
            request = self._requests[item["id"]]
            request.setresponse(item)
        else:
            self._send_error(item, "Unknown format")
        return True
Пример #10
0
            def wrapper(self, mess, args):

                # Some clients automatically convert consecutive dashes into a fancy
                # hyphen, which breaks long-form arguments. Undo this conversion to
                # provide a better user experience.
                args = shlex.split(args.replace('—', '--'))
                try:
                    parsed_args = err_command_parser.parse_args(args)
                except ArgumentParseError as e:
                    yield "I'm sorry, I couldn't parse that; %s" % e
                    yield err_command_parser.format_usage()
                    return
                except HelpRequested:
                    yield err_command_parser.format_help()
                    return

                if unpack_args:
                    func_args = []
                    func_kwargs = vars(parsed_args)
                else:
                    func_args = [parsed_args]
                    func_kwargs = {}

                if inspect.isgeneratorfunction(func):
                    for reply in func(self, mess, *func_args, **func_kwargs):
                        yield reply
                else:
                    yield func(self, mess, *func_args, **func_kwargs)
Пример #11
0
    def __init__(self, method, handler, *,
                 expect_handler=None,
                 resource=None):

        if expect_handler is None:
            expect_handler = _defaultExpectHandler

        assert asyncio.iscoroutinefunction(expect_handler), \
            'Coroutine is expected, got {!r}'.format(expect_handler)

        method = upstr(method)
        if method not in self.METHODS:
            raise ValueError("{} is not allowed HTTP method".format(method))

        assert callable(handler), handler
        if asyncio.iscoroutinefunction(handler):
            pass
        elif inspect.isgeneratorfunction(handler):
            warnings.warn("Bare generators are deprecated, "
                          "use @coroutine wrapper", DeprecationWarning)
        elif (isinstance(handler, type) and
              issubclass(handler, AbstractView)):
            pass
        else:
            handler = asyncio.coroutine(handler)

        self._method = method
        self._handler = handler
        self._expect_handler = expect_handler
        self._resource = resource
Пример #12
0
    def run(self, module, task, response):
        """
        Processing the task, catching exceptions and logs, return a `ProcessorResult` object
        """
        logger = module.logger
        result = None
        exception = None
        stdout = sys.stdout
        self.task = task
        self.response = response

        try:
            sys.stdout = ListO(module.log_buffer)
            if inspect.isgeneratorfunction(self._run):
                for result in self._run(task, response):
                    self._run_func(self.on_result, result, response, task)
            else:
                result = self._run(task, response)
                self._run_func(self.on_result, result, response, task)
        except Exception as e:
            logger.exception(e)
            exception = e
        finally:
            self.task = None
            self.response = None
            sys.stdout = stdout
            follows = self._follows
            messages = self._messages
            logs = list(module.log_buffer)
            extinfo = self._extinfo

        module.log_buffer[:] = []
        return ProcessorResult(result, follows, messages, logs, exception, extinfo)
Пример #13
0
    def make_cleanup(func):
        if inspect.isgeneratorfunction(func):
            @functools.wraps(func)
            def wrapped_callable(*args, **kwargs):
                original_units_registry = matplotlib.units.registry.copy()
                original_settings = mpl.rcParams.copy()
                matplotlib.style.use(style)
                try:
                    for yielded in func(*args, **kwargs):
                        yield yielded
                finally:
                    _do_cleanup(original_units_registry,
                                original_settings)
        else:
            @functools.wraps(func)
            def wrapped_callable(*args, **kwargs):
                original_units_registry = matplotlib.units.registry.copy()
                original_settings = mpl.rcParams.copy()
                matplotlib.style.use(style)
                try:
                    func(*args, **kwargs)
                finally:
                    _do_cleanup(original_units_registry,
                                original_settings)

        return wrapped_callable
Пример #14
0
 def decorator(func):
     if inspect.isgeneratorfunction(func):
         raise ConfigureError(
             'Cannot decorate generator functions with @depends')
     func, glob = self._prepare_function(func)
     depends = DependsFunction(self, func, dependencies, when=when)
     return depends.sandboxed
Пример #15
0
    def map_doc(self, doc):
        """run all map functions on a document"""

        _set_vs(self, ["emit", "log"])
        results = []

        for func in self.map_funcs:
            self._clear_state()

            try:
                if inspect.isgeneratorfunction(func):
                    for y in func(doc):
                        self.emit(*y)
                else:
                    func(doc)
            except:
                results.append([])
                self.exception("map_runtime_error", fatal=False, doc_id=doc["_id"], func=func)
            else:
                results.append(self.emissions)

        _set_vs(None)
        self._clear_state()

        self.output(*results)
Пример #16
0
    def loadCommands(self):
        commands = {}
        path = yield self.config.get("path","commands")
        for loader, name, ispkg in pkgutil.iter_modules([path]):
            if ispkg:
                continue
            try:
                command = getattr(__import__(path, fromlist=[name.encode("utf8")]), name)
                reload(command)
                command.config["name"] = name
                command.config["command"] = coroutine(command.command) if inspect.isgeneratorfunction(command.command) else command.command
                args, varg, vkwarg, kwargs = inspect.getargspec(command.command)

                if args[:5] != ["guid", "manager", "irc", "channel", "user"]:
                    continue

                if kwargs:
                    boundary = -1 * len(kwargs)
                    command.config["args"] = args[5:boundary]
                    command.config["kwargs"] = args[boundary:]
                else:
                    command.config["args"] = args[5:]
                    command.config["kwargs"] = []
                command.config["varg"] = varg
                command.config["vkwarg"] = vkwarg

                if "disabled" in command.config and command.config["disabled"]:
                    continue

                commands[name] = command.config
            except:
                self.err("Failed to load {}.{}", path, name)
        self.commands = commands
Пример #17
0
def tcp_server(server_prog, *,
               family=socket.AF_INET,
               addr=None,
               timeout=5,
               backlog=1,
               max_clients=10):

    if addr is None:
        if family == socket.AF_UNIX:
            with tempfile.NamedTemporaryFile() as tmp:
                addr = tmp.name
        else:
            addr = ('127.0.0.1', 0)

    if not inspect.isgeneratorfunction(server_prog):
        raise TypeError('server_prog: a generator function was expected')

    sock = socket.socket(family, socket.SOCK_STREAM)

    if timeout is None:
        raise RuntimeError('timeout is required')
    if timeout <= 0:
        raise RuntimeError('only blocking sockets are supported')
    sock.settimeout(timeout)

    try:
        sock.bind(addr)
        sock.listen(backlog)
    except OSError as ex:
        sock.close()
        raise ex

    srv = Server(sock, server_prog, timeout, max_clients)
    return srv
Пример #18
0
def coroutine(function):

    if inspect.isgeneratorfunction(function):
        routine = function
    else:
        @functools.wraps(function)
        def routine(*args, **kwargs):
            # calls the underlying function with the expected arguments
            # and keyword arguments (proper call propagation)
            result = function(*args, **kwargs)

            # verifies the data type of the resulting object so that a
            # proper yielding operation or return will take place
            is_future_ = is_future(result)
            is_generator = inspect.isgenerator(result)

            # in case the returned value is either a future or a generator
            # the complete set of yielded elements are propagated and
            # the result is stored as the "new" result
            if is_future_ or is_generator:
                result = yield from result

            # returns the "final" result to the caller method as expected
            # this allows generated propagation
            return result

    @functools.wraps(function)
    def wrapper(*args, **kwargs):
        generator = routine(*args, **kwargs)
        awaitable = AwaitWrapper(generator)
        return awaitable

    wrapper._is_coroutine = True
    return wrapper
Пример #19
0
    def _execute_and_send(self, cmd, args, match, mess, template_name=None):
        """Execute a bot command and send output back to the caller

        cmd: The command that was given to the bot (after being expanded)
        args: Arguments given along with cmd
        match: A re.MatchObject if command is coming from a regex-based command, else None
        mess: The message object
        template_name: The name of the jinja template which should be used to render
            the markdown output, if any

        """
        private = cmd in self.bot_config.DIVERT_TO_PRIVATE
        commands = self.re_commands if match else self.commands
        try:
            if inspect.isgeneratorfunction(commands[cmd]):
                replies = commands[cmd](mess, match) if match else commands[cmd](mess, args)
                for reply in replies:
                    if reply:
                        self.send_simple_reply(mess, self.process_template(template_name, reply), private)
            else:
                reply = commands[cmd](mess, match) if match else commands[cmd](mess, args)
                if reply:
                    self.send_simple_reply(mess, self.process_template(template_name, reply), private)
        except Exception as e:
            tb = traceback.format_exc()
            log.exception('An error happened while processing '
                          'a message ("%s"): %s"' %
                          (mess.body, tb))
            self.send_simple_reply(mess, self.MSG_ERROR_OCCURRED + ':\n %s' % e, private)
Пример #20
0
    def _create_future(self, func, args, kwargs, filtered_args_dict, should_submit):
        if not func.version_info['ignore_deps']:
            # TODO: Check a map of possible dependencies executed for
            # this run here, in case a depdency just got changed. This
            # should be done by consulting a pickled on-file database
            # AFAICT.
            raise NotImplementedError('Please use ignore_deps for now')

        # Make job_path containing hashes
        h = NumpyHasher('sha1')
        h.hash((func.version_info['digest'], filtered_args_dict))
        job_name = '%s-%s' % (func.__name__,
                              self._encode_digest(h._hash.digest()))
        # Construct job dir if not existing. Remember that we may
        # race for this; if we got to create the directory, we have
        # the lock.
        we_made_it = self._ensure_job_dir(job_name, func, args, kwargs)
        is_generator = inspect.isgenerator(func) or inspect.isgeneratorfunction(func)
        future = self._create_future_from_job_dir(job_name, is_generator)
        if we_made_it:
            self.logger.info('Created job: %s' % job_name)
            if should_submit:
                jobid = future.submit()
                self.logger.info('Submitted job as %s: %s' % (jobid, job_name))
        else:
            self.logger.info('Job already exists: %s' % job_name)
        return future
Пример #21
0
def task(function):
    '''Thread-safe decorator to run a ``function`` in an event loop.

    :param function: a callable which can return coroutines,
        :class:`.asyncio.Future` or synchronous data. Can be a method of
        an :ref:`async object <async-object>`, in which case the loop
        is given by the object ``_loop`` attribute.
    :return: a :class:`~asyncio.Future`
    '''
    if isgeneratorfunction(function):
        wrapper = function
    else:
        @coroutine
        def wrapper(*args, **kw):
            res = function(*args, **kw)
            if isawaitable(res):
                res = yield from res
            return res

    @wraps(function)
    def _(*args, **kwargs):
        loop = getattr(args[0], '_loop', None) if args else None
        coro = wrapper(*args, **kwargs)
        return ensure_future(coro, loop=loop)

    return _
Пример #22
0
def coroutine(func):
    """Decorator to mark coroutines.

    If the coroutine is not yielded from before it is destroyed,
    an error message is logged.
    """
    if inspect.isgeneratorfunction(func):
        coro = func
    else:
        @functools.wraps(func)
        def coro(*args, **kw):
            res = func(*args, **kw)
            if isinstance(res, futures.Future) or inspect.isgenerator(res):
                res = yield from res
            return res

    if not _DEBUG:
        wrapper = coro
    else:
        @functools.wraps(func)
        def wrapper(*args, **kwds):
            w = CoroWrapper(coro(*args, **kwds), func)
            if w._source_traceback:
                del w._source_traceback[-1]
            w.__name__ = func.__name__
            if hasattr(func, '__qualname__'):
                w.__qualname__ = func.__qualname__
            w.__doc__ = func.__doc__
            return w

    wrapper._is_coroutine = True  # For iscoroutinefunction().
    return wrapper
Пример #23
0
 def setcallable(self, key, function, *args):
     if key not in self.keyValues:
         if inspect.isgeneratorfunction(function):
             self.keyValues[key] = list(function(*args))
         else:
             self.keyValues[key] = function(*args)
     return self.keyValues[key]
Пример #24
0
def coroutine(func):
    """
    Mark a function as a compatible coroutine.

    A compatible coroutine can be used on both Python 2 and Python 3. The
    corresponding coroutine object can be turned into a future using
    :class:`.Task`.

    Compatible coroutines are written using :func:`.Return` and :func:`.From`,
    in a similar way to Trollius.

    """
    if inspect.isgeneratorfunction(func):
        coro = func
    else:
        @functools.wraps(func)
        def coro(*args, **kw):
            res = func(*args, **kw)
            if False:
                yield
            raise Return(res)

    # We could potentially add a flag to the returned coroutine object here, to
    # be checked by `Task` however for now this decorator just serves as
    # documentation.
    coro._is_compat_coroutine = True
    return coro
Пример #25
0
            def wrapper(self, msg, args):

                # Attempt to sanitize arguments of bad characters
                try:
                    sanitizer_re = re.compile('|'.join(re.escape(ii) for ii in ARG_BOTCMD_CHARACTER_REPLACEMENTS))
                    args = sanitizer_re.sub(lambda mm: ARG_BOTCMD_CHARACTER_REPLACEMENTS[mm.group()], args)
                    args = shlex.split(args)
                    parsed_args = err_command_parser.parse_args(args)
                except ArgumentParseError as e:
                    yield "I'm sorry, I couldn't parse the arguments; %s" % e
                    yield err_command_parser.format_usage()
                    return
                except HelpRequested:
                    yield err_command_parser.format_help()
                    return
                except ValueError as ve:
                    yield "I'm sorry, I couldn't parse this command; %s" % ve
                    yield err_command_parser.format_help()
                    return

                if unpack_args:
                    func_args = []
                    func_kwargs = vars(parsed_args)
                else:
                    func_args = [parsed_args]
                    func_kwargs = {}

                if inspect.isgeneratorfunction(func):
                    for reply in func(self, msg, *func_args, **func_kwargs):
                        yield reply
                else:
                    yield func(self, msg, *func_args, **func_kwargs)
Пример #26
0
    def __init__(self, func):
        func = get_function_object(func)
        code = get_code_object(func)
        pysig = utils.pysignature(func)
        if not code:
            raise errors.ByteCodeSupportError(
                "%s does not provide its bytecode" % func)

        # A map of {offset: ByteCodeInst}
        table = utils.SortedMap(ByteCodeIter(code))
        labels = set(dis.findlabels(code.co_code))
        labels.add(0)

        try:
            func_qualname = func.__qualname__
        except AttributeError:
            func_qualname = func.__name__

        self._mark_lineno(table, code)
        super(ByteCode, self).__init__(func=func,
                                       func_qualname=func_qualname,
                                       is_generator=inspect.isgeneratorfunction(func),
                                       pysig=pysig,
                                       filename=code.co_filename,
                                       co_names=code.co_names,
                                       co_varnames=code.co_varnames,
                                       co_consts=code.co_consts,
                                       co_freevars=code.co_freevars,
                                       table=table,
                                       labels=list(sorted(labels)))
Пример #27
0
    def inner(*args, **kwargs):
        """
        Wrap func to check if we've already entered this function and if
        so replace it with a no-op.
        """

        def generator():
            """
            Hide the generator in a separate function
            because Python 2 can't support "returning from generators"
            """
            if entered[0]:
                yield
            else:
                try:
                    entered[0] = True
                    for val in func(*args, **kwargs):
                        yield val
                finally:
                    entered[0] = False

        if inspect.isgeneratorfunction(func):
            return generator()
        else:
            if not entered[0]:
                try:
                    entered[0] = True
                    return func(*args, **kwargs)
                finally:
                    entered[0] = False
Пример #28
0
def isgenerator(func):
    if PYTHON_VERSION_MAJOR == 3:
        return inspect.isgeneratorfunction(func)
    try:
        return func.func_code.co_flags & CO_GENERATOR != 0
    except AttributeError:
        return False
Пример #29
0
 def decorator( method: Callable[..., Generator[T, None, R]],
 ) -> Callable[..., Generator[T, None, R]]:
     assert isgeneratorfunction(method)
     @wraps(method)
     def wrapper( self: Any, target: Target, *args: Any,
         _seen_targets: Optional[Set[Target]] = None,
         **kwargs: Any
     ) -> Any:
         if _seen_targets is None:
             _seen_targets = set()
         if skip_check is None:
             checking = True
         else:
             checking = not skip_check(self, target, *args, **kwargs)
         if checking:
             if target in _seen_targets:
                 raise DriverError(f"Cycle detected from {target}")
             else:
                 _seen_targets.add(target)
         try:
             return ( yield from
                 method( self, target, *args,
                     _seen_targets=_seen_targets, **kwargs )
             )
         finally:
             if checking:
                 _seen_targets.discard(target)
     return wrapper
Пример #30
0
def tsv_extractor(generator):
  """
  When a generator function is decorated with this (i.e., @tsv_extractor
  preceding the def line), standard input is parsed as Postgres-style TSV
  (PGTSV) input rows, the function is applied to generate output rows, and then
  checks that each line of this generator is in the output format before
  printing back as PGTSV rows.
  """
  # Expects the input and output formats to have been decorated with @over and @returns
  try:
    # @over has precedence over default values of function arguments
    input_format = generator.input_format
  except AttributeError:
    input_format = format_from_args_defaults_of(generator)
  try:
    output_format = generator.output_format
    # also support function argument defaults for output_format for symmetry
    output_format = format_from_args_defaults_of(output_format)
  except AttributeError:
    raise ValueError("The function must be decorated with @returns")
    # TODO or maybe just skip type checking if @returns isn't present?
  # Check generator function
  if not isgeneratorfunction(generator):
    raise ValueError("The function must be a *generator*, i.e., use yield not return")

  # Create the input parser
  parser = PGTSVParser(input_format)

  # Create the output parser
  printer = PGTSVPrinter(output_format)

  for row in parser.parse_stdin():
    for out_row in generator(**row._asdict()):
      printer.write(out_row)
Пример #31
0
 def decorator(func):
     if inspect.isgeneratorfunction(func):
         func = inlineCallbacks(func)
     self._signals.setdefault(name, []).append(func)
     return func
Пример #32
0
    def decorate_callable(self, func):
        if hasattr(func, 'patchings'):
            func.patchings.append(self)
            return func

        is_generator_func = inspect.isgeneratorfunction(func)
        is_coroutine_func = asyncio.iscoroutinefunction(func)
        if not (is_generator_func or is_coroutine_func):
            return super().decorate_callable(func)

        @functools.wraps(func)
        def patched(*args, **keywargs):
            extra_args = []
            entered_patchers = []

            exc_info = tuple()
            try:
                for patching in patched.patchings:
                    arg = patching.__enter__()
                    entered_patchers.append(patching)
                    if patching.attribute_name is not None:
                        keywargs.update(arg)
                        if patching.new is DEFAULT:
                            patching.new = arg[patching.attribute_name]
                    elif patching.new is DEFAULT:
                        patching.new = arg
                        extra_args.append(arg)

                args += tuple(extra_args)
                gen = func(*args, **keywargs)
                return _PatchedGenerator(gen, patched.patchings,
                                         asyncio.iscoroutinefunction(func))
            except:
                if patching not in entered_patchers and unittest.mock._is_started(
                        patching):
                    # the patcher may have been started, but an exception
                    # raised whilst entering one of its additional_patchers
                    entered_patchers.append(patching)
                # Pass the exception to __exit__
                exc_info = sys.exc_info()
                # re-raise the exception
                raise
            finally:
                for patching in reversed(entered_patchers):
                    patching.__exit__(*exc_info)

        patched.patchings = [self]

        if is_generator_func:
            # wrap the patched object in a generator so
            # inspect.isgeneratorfunction() returns True
            @functools.wraps(func)
            def patched_generator(*args, **kwargs):
                return (yield from patched(*args, **kwargs))

            if is_coroutine_func:
                return asyncio.coroutine(patched_generator)
            else:
                return patched_generator
        else:
            return functools.wraps(func)(patched)
Пример #33
0
    def signature(cls, f):
        r"""Construct a Signature object describing `f`

        Compute a Signature so that we can write a function wrapping f with
        the same signature and call-type.

        Parameters
        ----------
        f : callable
            A function to be decorated

        Returns
        -------
        sig : argmap.Signature
            The Signature of f

        Notes
        -----
        The Signature is a namedtuple with names:

            name : a unique version of the name of the decorated function
            signature : the inspect.signature of the decorated function
            def_sig : a string used as code to define the new function
            call_sig : a string used as code to call the decorated function
            names : a dict keyed by argument name and index to the argument's name
            n_positional : the number of positional arguments in the signature
            args : the name of the VAR_POSITIONAL argument if any, i.e. \*theseargs
            kwargs : the name of the VAR_KEYWORDS argument if any, i.e. \*\*kwargs

        These named attributes of the signature are used in `assemble` and `compile`
        to construct a string of source code for the decorated function.

        """
        sig = inspect.signature(f, follow_wrapped=False)
        def_sig = []
        call_sig = []
        names = {}

        kind = None
        args = None
        kwargs = None
        npos = 0
        for i, param in enumerate(sig.parameters.values()):
            # parameters can be position-only, keyword-or-position, keyword-only
            # in any combination, but only in the order as above.  we do edge
            # detection to add the appropriate punctuation
            prev = kind
            kind = param.kind
            if prev == param.POSITIONAL_ONLY != kind:
                # the last token was position-only, but this one isn't
                def_sig.append("/")
            if prev != param.KEYWORD_ONLY == kind != param.VAR_POSITIONAL:
                # param is the first keyword-only arg and isn't starred
                def_sig.append("*")

            # star arguments as appropriate
            if kind == param.VAR_POSITIONAL:
                name = "*" + param.name
                args = param.name
                count = 0
            elif kind == param.VAR_KEYWORD:
                name = "**" + param.name
                kwargs = param.name
                count = 0
            else:
                names[i] = names[param.name] = param.name
                name = param.name
                count = 1

            # assign to keyword-only args in the function call
            if kind == param.KEYWORD_ONLY:
                call_sig.append(f"{name} = {name}")
            else:
                npos += count
                call_sig.append(name)

            def_sig.append(name)

        fname = cls._name(f)
        def_sig = f'def {fname}({", ".join(def_sig)}):'

        if inspect.isgeneratorfunction(f):
            _return = "yield from"
        else:
            _return = "return"

        call_sig = f"{_return} {{}}({', '.join(call_sig)})"

        return cls.Signature(fname, sig, def_sig, call_sig, names, npos, args,
                             kwargs)
Пример #34
0
import asyncio, os, inspect, logging, functools
Пример #35
0
    def construct(self, data=None):
        """
        Construct the expression(s) for this logical constraint.
        """
        generate_debug_messages = \
            __debug__ and logger.isEnabledFor(logging.DEBUG)
        if generate_debug_messages:
            logger.debug("Constructing logical constraint list %s"
                         % self.name)

        if self._constructed:
            return
        self._constructed = True

        assert self._init_expr is None
        _init_rule = self.rule

        #
        # We no longer need these
        #
        self._init_expr = None
        # Utilities like DAE assume this stays around
        # self.rule = None

        if _init_rule is None:
            return

        _generator = None
        _self_parent = self._parent()
        if inspect.isgeneratorfunction(_init_rule):
            _generator = _init_rule(_self_parent)
        elif inspect.isgenerator(_init_rule):
            _generator = _init_rule
        if _generator is None:
            while True:
                val = len(self._index) + 1
                if generate_debug_messages:
                    logger.debug(
                        "   Constructing logical constraint index " + str(val))
                expr = apply_indexed_rule(self,
                                          _init_rule,
                                          _self_parent,
                                          val)
                if expr is None:
                    raise ValueError(
                        "LogicalConstraintList '%s': rule returned None "
                        "instead of LogicalConstraintList.End" % (self.name,))
                if (expr.__class__ is tuple) and \
                        (expr == LogicalConstraintList.End):
                    return
                self.add(expr)

        else:

            for expr in _generator:
                if expr is None:
                    raise ValueError(
                        "LogicalConstraintList '%s': generator returned None "
                        "instead of LogicalConstraintList.End" % (self.name,))
                if (expr.__class__ is tuple) and \
                        (expr == LogicalConstraintList.End):
                    return
                self.add(expr)
Пример #36
0
    def __init__(self,
                 func: Callable,
                 frame=None,
                 args: tuple = None,
                 kwargs: Dict[str, Any] = None,
                 forward_refs_policy=ForwardRefPolicy.ERROR):
        self.func = func
        self.func_name = function_name(func)
        self.signature = inspect.signature(func)
        self.typevars = {}  # type: Dict[Any, type]
        self.is_generator = isgeneratorfunction(func)

        if args is not None and kwargs is not None:
            self.arguments = self.signature.bind(*args, **kwargs).arguments
        else:
            assert frame, 'frame must be specified if args or kwargs is None'
            self.arguments = frame.f_locals.copy()

        self.type_hints = _type_hints_map.get(func)
        if self.type_hints is None:
            while True:
                try:
                    hints = get_type_hints(func)
                except NameError as exc:
                    if forward_refs_policy is ForwardRefPolicy.ERROR:
                        raise

                    typename = str(exc).split("'", 2)[1]
                    for param in self.signature.parameters.values():
                        if param.annotation == typename:
                            break
                    else:
                        raise

                    func_name = function_name(func)
                    if forward_refs_policy is ForwardRefPolicy.GUESS:
                        if param.name in self.arguments:
                            argtype = self.arguments[param.name].__class__
                            if param.annotation == argtype.__qualname__:
                                func.__annotations__[param.name] = argtype
                                msg = (
                                    'Replaced forward declaration {!r} in {} with {!r}'
                                    .format(param.annotation, func_name,
                                            argtype))
                                warn(TypeHintWarning(msg))
                                continue

                    msg = 'Could not resolve type hint {!r} on {}: {}'.format(
                        param.annotation, function_name(func), exc)
                    warn(TypeHintWarning(msg))
                    del func.__annotations__[param.name]
                else:
                    break

            self.type_hints = OrderedDict()
            for name, parameter in self.signature.parameters.items():
                if name in hints:
                    annotated_type = hints[name]

                    # PEP 428 discourages it by MyPy does not complain
                    if parameter.default is None:
                        annotated_type = Optional[annotated_type]

                    if parameter.kind == Parameter.VAR_POSITIONAL:
                        self.type_hints[name] = Tuple[annotated_type, ...]
                    elif parameter.kind == Parameter.VAR_KEYWORD:
                        self.type_hints[name] = Dict[str, annotated_type]
                    else:
                        self.type_hints[name] = annotated_type

            if 'return' in hints:
                self.type_hints['return'] = hints['return']

            _type_hints_map[func] = self.type_hints
Пример #37
0
    def decorator(func):
        """Decorator for the given function."""
        tries = retries + 1
        is_generator = inspect.isgeneratorfunction(func)
        function_with_type = function
        if is_generator:
            function_with_type += ' (generator)'

        def handle_retry(num_try, exception=None):
            """Handle retry."""

            if (exception is None or isinstance(
                    exception, exception_type)) and num_try < tries:
                logs.info('Retrying on %s failed with %s. Retrying again.',
                          function_with_type,
                          sys.exc_info()[1])
                sleep(get_delay(num_try, delay, backoff))
                return True

            logs.error('Retrying on %s failed with %s. Raise.',
                       function_with_type,
                       sys.exc_info()[1])
            return False

        @functools.wraps(func)
        def _wrapper(*args, **kwargs):
            """Regular function wrapper."""

            for num_try in range(1, tries + 1):
                try:
                    result = func(*args, **kwargs)
                    if retry_on_false and not result:
                        if not handle_retry(num_try):
                            return result

                        continue

                    return result
                except Exception as error:  # pylint: disable=broad-except
                    if not handle_retry(num_try, exception=error):
                        raise

        @functools.wraps(func)
        def _generator_wrapper(*args, **kwargs):
            """Generator function wrapper."""
            # This argument is not applicable for generator functions.
            assert not retry_on_false

            already_yielded_element_count = 0
            for num_try in range(1, tries + 1):
                try:
                    for index, result in enumerate(func(*args, **kwargs)):
                        if index >= already_yielded_element_count:
                            yield result
                            already_yielded_element_count += 1
                    break
                except Exception as error:  # pylint: disable=broad-except
                    if not handle_retry(num_try, exception=error):
                        raise

        if is_generator:
            return _generator_wrapper
        return _wrapper
Пример #38
0
def str_file(func, **kwargs):
    """A decorator to automatically open arguments that are files.

    If there are kwargs then they are name=mode. When the function is
    called if the argument name is a string then the file is opened with
    mode.

    If there are no kwargs then it is assumed the first argument is a
    file that should be opened as 'r'
    """
    possible_files = kwargs
    # We need to have the generator check out here so that the inner function is
    # either a generator (has a yield) or not. If we were to try to have this if
    # inside of the open_files then we would always return a generator.
    if inspect.isgeneratorfunction(func):

        @six.wraps(func)
        def open_files(*args, **kwargs):
            # If no arg names are given then assume the first arg is a file
            # you want to read from.
            if not possible_files:
                if isinstance(args[0], six.string_types):
                    with io.open(args[0], mode='r', encoding='utf-8') as f:
                        # Call the function with the file instead we need to
                        # yield from it until it is done other wise the file
                        # will be closed after the first yield.
                        for x in func(f, *args[1:], **kwargs):
                            yield x
                else:
                    for x in func(*args, **kwargs):
                        yield x
            else:
                # Otherwise we have multiple files we want to open
                to_close = []
                # Get a dict representation of what it will look like if we
                # call func with *args and **kwargs
                arg = inspect.getcallargs(func, *args, **kwargs)
                try:
                    for f, mode in possible_files.items():
                        if isinstance(arg[f], six.string_types):
                            # Replace strings with the opened files
                            arg[f] = io.open(arg[f],
                                             mode=mode,
                                             encoding='utf-8')
                            to_close.append(f)
                    # Call the function with the files instead
                    for x in func(**arg):
                        yield x
                finally:
                    # Make sure to close the files
                    for f in to_close:
                        arg[f].close()
    else:

        @six.wraps(func)
        def open_files(*args, **kwargs):
            # If no arg names are given then assume the first arg is a file
            # you want to read from.
            if not possible_files:
                if isinstance(args[0], six.string_types):
                    with io.open(args[0], mode='r', encoding='utf-8') as f:
                        # Call the function with the file instead
                        return func(f, *args[1:], **kwargs)
                else:
                    return func(*args, **kwargs)
            else:
                # Otherwise we have multiple files we want to open
                to_close = []
                # Get a dict representation of what it will look like if we
                # call func with *args and **kwargs
                arg = inspect.getcallargs(func, *args, **kwargs)
                try:
                    for f, mode in possible_files.items():
                        if isinstance(arg[f], six.string_types):
                            # Replace strings with the opened files
                            arg[f] = io.open(arg[f],
                                             mode=mode,
                                             encoding='utf-8')
                            to_close.append(f)
                    # Call the function with the files instead
                    return func(**arg)
                finally:
                    # Make sure to close the files
                    for f in to_close:
                        arg[f].close()

    return open_files
Пример #39
0
def coroutine(func):
    """Decorator to mark coroutines.

    If the coroutine is not yielded from before it is destroyed,
    an error message is logged.
    """
    if _inspect_iscoroutinefunction(func):
        # In Python 3.5 that's all we need to do for coroutines
        # defiend with "async def".
        # Wrapping in CoroWrapper will happen via
        # 'sys.set_coroutine_wrapper' function.
        return func

    if inspect.isgeneratorfunction(func):
        coro = func
    else:

        @_wraps(func)
        def coro(*args, **kw):
            res = func(*args, **kw)
            if (isinstance(res, futures._FUTURE_CLASSES)
                    or inspect.isgenerator(res)):
                res = yield From(res)
            elif _AwaitableABC is not None:
                # If 'func' returns an Awaitable (new in 3.5) we
                # want to run it.
                try:
                    await_meth = res.__await__
                except AttributeError:
                    pass
                else:
                    if isinstance(res, _AwaitableABC):
                        res = yield From(await_meth())
            raise Return(res)

    if _PEP479:
        # FIXME: use @_wraps
        coro = pep479_wrapper(func, coro)
        coro = _wraps(func)(coro)

    if not _DEBUG:
        if _types_coroutine is None:
            wrapper = coro
        else:
            wrapper = _types_coroutine(coro)
    else:

        @_wraps(func)
        def wrapper(*args, **kwds):
            w = CoroWrapper(coro(*args, **kwds), func=func)
            if w._source_traceback:
                del w._source_traceback[-1]
            # Python < 3.5 does not implement __qualname__
            # on generator objects, so we set it manually.
            # We use getattr as some callables (such as
            # functools.partial may lack __qualname__).
            w.__name__ = getattr(func, '__name__', None)
            w.__qualname__ = getattr(func, '__qualname__', None)
            return w

    wrapper._is_coroutine = True  # For iscoroutinefunction().
    return wrapper
Пример #40
0
assert bool(type(CompiledClass.compiledMethod) == types.MethodType) == (
    sys.version_info < (3, ))

print("Compiled method:", inspect.getargspec(CompiledClass().compiledMethod))
print(
    "Compiled class:",
    inspect.formatargspec(*inspect.getargspec(CompiledClass().compiledMethod)))


def compiledGenerator():
    yield 1


assert inspect.isfunction(compiledGenerator) is True
assert inspect.isgeneratorfunction(compiledGenerator) is True

assert isinstance(compiledGenerator(), types.GeneratorType) is True
assert type(compiledGenerator()) == types.GeneratorType
assert isinstance(compiledGenerator, types.GeneratorType) is False

assert inspect.ismethod(compiledGenerator()) is False
assert inspect.isfunction(compiledGenerator()) is False

assert inspect.isgenerator(compiledFunction) is False
assert inspect.isgenerator(compiledGenerator) is False
assert inspect.isgenerator(compiledGenerator()) is True


def someFunction(a):
    assert inspect.isframe(sys._getframe())
Пример #41
0
def pytest_pycollect_makeitem(collector, name, obj):
    if collector.funcnamefilter(name) and inspect.isgeneratorfunction(obj):
        item = pytest.Function(name, parent=collector)
        if 'gen_test' in item.keywords:
            return list(collector._genfunctions(name, obj))
Пример #42
0
        def decorate_with_data(routine):
            # passthrough an already decorated routine:
            # (could this be any uglier?)
            if hasattr(routine, 'setup'):
                def passthru_setup():
                    routine.setup()
                    if setup: setup()
            else:
                passthru_setup = setup
            if hasattr(routine, 'teardown'):
                def passthru_teardown():
                    routine.teardown()
                    if teardown: teardown()
            else:
                passthru_teardown = teardown
            
            def setup_data():
                data = self.data(*datasets)
                data.setup()
                return data
            def teardown_data(data):
                data.teardown()
        
            @wraps(routine)
            def call_routine(*a,**kw):
                data = setup_data()
                try:
                    routine(data, *a, **kw)
                except KeyboardInterrupt:
                    # user wants to abort everything :
                    raise
                except Exception as exc:
                    # caught exception, so try to teardown but do it safely :
                    try:
                        teardown_data(data)
                    except:
                        t_ident = ("-----[exception in teardown %s]-----" % 
                                    hex(id(teardown_data)))
                        sys.stderr.write("\n\n%s\n" % t_ident)
                        traceback.print_exc()
                        sys.stderr.write("%s\n\n" % t_ident)
                    reraise(exc.__class__, exc)
                else:
                    teardown_data(data)
    
            @wraps(routine)
            def iter_routine():
                for stack in routine():
                    fn = stack[0]
                    try:
                        args = stack[1:]
                    except IndexError:
                        args = tuple([])
                    def atomic_routine(*genargs,**kw):
                        setup_data = genargs[0]
                        data = setup_data()
                        try:
                            genargs = genargs[1:]
                        except IndexError:
                            genargs = tuple([])
                        genargs = (data,) + genargs
                        try:
                            fn(*genargs, **kw)
                        except Exception as exc:
                            try:
                                teardown_data(data)
                            except:
                                t_ident = (
                                    "-----[exception in teardown %s]-----" % 
                                    hex(id(teardown_data)))
                                sys.stderr.write("\n\n%s\n" % t_ident)
                                traceback.print_exc()
                                sys.stderr.write("%s\n\n" % t_ident)
                            reraise(exc.__class__, exc)
                        else:
                            teardown_data(data)
                    
                    restack = (atomic_routine, setup_data) + args
                    yield restack

            if isgeneratorfunction(routine):
                wrapped_routine = iter_routine
            else:
                wrapped_routine = call_routine
        
            decorate = with_setup(  setup=passthru_setup, 
                                    teardown=passthru_teardown )
            return decorate( wrapped_routine )
Пример #43
0
from collections.abc import Iterable
import types


def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield (b)  # 使用yield
        #print(b)
        a, b = b, a + b
        n = n + 1


# fab是生成器函数,而fab(10)是调用fab函数返回的一个生成器
# 好比类的定义和类的实例的区别

# fab()
if isgeneratorfunction(fab):
    print("fab is a generator function")

if isinstance(fab, Iterable) == False:
    print('fab is not iterable')
print("")

# fab(10)
if isinstance(fab(10), types.GeneratorType):
    print("fab(10) is a instance")

if isinstance(fab(10), Iterable) == True:
    print('fab(10) is iterable')
Пример #44
0
def is_generator(obj):
    return callable(obj) and (isgeneratorfunction(obj)
                              or isgeneratorfunction(getattr(obj, '__call__')))
Пример #45
0
    async def _negotiate(self, initiator):
        """
        (*Coroutine*) Handle the establishment of the WebRTC peer connection.
        """
        ice_servers = [
            RTCIceServer('stun:stun.l.google.com:19302'),
            RTCIceServer('stun:stun2.l.google.com:19302'),
            RTCIceServer('stun:stunserver.org:3478')
        ]

        self._pc = RTCPeerConnection(RTCConfiguration(ice_servers))

        async def add_datachannel_listeners():
            """
            Set the listeners to handle data channel events
            """
            @self._datachannel.on('message')
            async def on_message(message):
                try:
                    data = json.loads(message)
                except:
                    raise TypeError('Received an invalid json message data')
                self._data = data
                try:
                    for handler in self._data_handlers:
                        if inspect.iscoroutinefunction(handler):
                            await handler(data)
                        else:
                            handler(data)
                except Exception as e:
                    logging.exception(e, traceback.format_exc())
                    raise e

            @self._datachannel.on('close')
            async def on_close():
                if self.readyState == PeerState.CONNECTED:
                    logging.info('Datachannel lost, disconnecting...')
                    self.disconnection_event.set()

            @self._datachannel.on('error')
            async def on_error(error):
                logging.error('Datachannel error: ' + str(error))
                self.disconnection_event.set()

        @self._pc.on('track')
        def on_track(track):
            """
            Set the consumer or destination of the incomming video and audio tracks
            """
            logging.info('Track %s received' % track.kind)

            if track.kind == 'audio':
                #webrtc_connection.addTrack(player.audio)
                #recorder.addTrack(track)
                pass
            elif track.kind == 'video':
                #local_video = VideoTransformTrack(track, transform=signal['video_transform'])
                #webrtc_connection.addTrack(local_video)
                if self._frame_consumer_feeder:
                    self._track_consumer_task = asyncio.create_task(
                        self._frame_consumer_feeder.feed_with(track))

            @track.on('ended')
            async def on_ended():
                logging.info('Remote track %s ended' % track.kind)
                if self.readyState == PeerState.CONNECTED:
                    logging.info('Remote media track ended, disconnecting...')
                    self.disconnection_event.set()
                #await recorder.stop()

        @self._pc.on('iceconnectionstatechange')
        async def on_iceconnectionstatechange():
            """
            Monitor the ICE connection state
            """
            logging.info('ICE connection state of peer (%s) is %s', self.id,
                         self._pc.iceConnectionState)
            if self._pc.iceConnectionState == 'failed':
                self.disconnection_event.set()
            elif self._pc.iceConnectionState == 'completed':
                # self._set_readyState(PeerState.CONNECTED)
                pass

        # Add media tracks
        if self._media_source:
            if self._media_source_format:
                self._player = MediaPlayer(self._media_source,
                                           format=self._media_source_format)
            else:
                self._player = MediaPlayer(self._media_source)
            if self._player.audio:
                self._pc.addTrack(self._player.audio)
            if self._player.video:
                self._pc.addTrack(self._player.video)

                @self._player.video.on('ended')
                async def on_ended():
                    logging.info('Local track %s ended' %
                                 self._player.video.kind)
                    if self.readyState == PeerState.CONNECTED:
                        logging.info('disconnecting...')
                        self.disconnection_event.set()

                logging.info('Video player track added')
        elif self._frame_generator:
            if inspect.isgeneratorfunction(self._frame_generator):
                self._pc.addTrack(
                    FrameGeneratorTrack(self._frame_generator,
                                        frame_rate=self._frame_rate))
                logging.info('Video frame generator track added')
            else:
                logging.info('No video track to add')

        if initiator:
            logging.info('Initiating peer connection...')
            do = self._datachannel_options
            if do:
                self._datachannel = self._pc.createDataChannel(
                    do['label'], do['maxPacketLifeTime'], do['maxRetransmits'],
                    do['ordered'], do['protocol'])
            else:
                self._datachannel = self._pc.createDataChannel('data_channel')
            await self._pc.setLocalDescription(await self._pc.createOffer())

            signal = {
                'sdp': self._pc.localDescription.sdp,
                'type': self._pc.localDescription.type
            }
            await self._send(signal)
            signal = await self._get_signal()
            if signal['type'] != 'answer':
                raise Exception('Expected answer from remote peer', signal)
            answer = RTCSessionDescription(sdp=signal['sdp'],
                                           type=signal['type'])
            await self._pc.setRemoteDescription(answer)

            @self._datachannel.on('open')
            async def on_open():
                self._set_readyState(PeerState.CONNECTED)
                await add_datachannel_listeners()
                pass  #asyncio.ensure_future(send_pings())
        else:
            logging.info('Waiting for peer connection...')

            @self._pc.on('datachannel')
            async def on_datachannel(channel):
                self._datachannel = channel
                self._set_readyState(PeerState.CONNECTED)
                await add_datachannel_listeners()

            signal = await self._get_signal()
            if signal['type'] != 'offer':
                raise Exception('Expected offer from remote peer', signal)
            offer = RTCSessionDescription(sdp=signal['sdp'],
                                          type=signal['type'])
            await self._pc.setRemoteDescription(offer)
            answer = await self._pc.createAnswer()
            await self._pc.setLocalDescription(answer)
            answer = {
                'sdp': self._pc.localDescription.sdp,
                'type': self._pc.localDescription.type
            }
            await self._send(answer)

        logging.info('starting _handle_candidates_task...')
        self._handle_candidates_task = asyncio.create_task(
            self._handle_ice_candidates())
        logging.info('sending local ice candidates...')

        # ice_servers = RTCIceGatherer.getDefaultIceServers()
        logging.debug(f'ice_servers: {ice_servers}')
        ice_gatherer = RTCIceGatherer(ice_servers)
        local_candidates = ice_gatherer.getLocalCandidates()
        logging.debug(f'local_candidates: {local_candidates}')
        for candidate in local_candidates:
            sdp = (
                f"{candidate.foundation} {candidate.component} {candidate.protocol} "
                f"{candidate.priority} {candidate.ip} {candidate.port} typ {candidate.type}"
            )

            if candidate.relatedAddress is not None:
                sdp += f" raddr {candidate.relatedAddress}"
            if candidate.relatedPort is not None:
                sdp += f" rport {candidate.relatedPort}"
            if candidate.tcpType is not None:
                sdp += f" tcptype {candidate.tcpType}"
            message = {
                "candidate": "candidate:" + sdp,
                "id": candidate.sdpMid,
                "label": candidate.sdpMLineIndex,
                "type": "candidate",
            }
            logging.info(message)
            await self._send(message)

        while self.readyState == PeerState.CONNECTING:
            await asyncio.sleep(0.2)

        if self._track_consumer_task:
            logging.info('starting _remote_track_monitor_task...')
            self._remote_track_monitor_task = asyncio.create_task(
                self._remote_track_monitor())

        self._connection_monitor_task = asyncio.create_task(
            self._connection_monitor())
Пример #46
0
 def _producer_iter(self):
     """A little helper to also support generator functions"""
     return self.producer() if inspect.isgeneratorfunction(
         self.producer) else self.producer
Пример #47
0
def is_gen_callable(call: Callable) -> bool:
    if inspect.isgeneratorfunction(call):
        return True
    call = getattr(call, "__call__", None)
    return inspect.isgeneratorfunction(call)
Пример #48
0
 def __init__(self, frame_generator):
     if not inspect.isgeneratorfunction(frame_generator):
         raise TypeError('frame_generator should be a generator function')
     super().__init__()  # don't forget this!
     self.generator = frame_generator()
     self.last_time = time.time()
Пример #49
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# 斐波那契数列
# F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)


def fab_with_yield(mx):
    x, y, n = 0, 1, 1
    while n < mx:
        yield y
        x, y = y, x + y
        n += 1


def test():
    for i in fab_with_yield(5):
        print(i)


test()

from inspect import isgeneratorfunction
print(isgeneratorfunction(fab_with_yield))

from collections import Iterable
print(isinstance(fab_with_yield, Iterable))
print(isinstance(fab_with_yield(5), Iterable))
Пример #50
0
def _format_coroutine(coro):
    assert iscoroutine(coro)

    if not hasattr(coro, 'cr_code') and not hasattr(coro, 'gi_code'):
        # Most likely a built-in type or a Cython coroutine.

        # Built-in types might not have __qualname__ or __name__.
        coro_name = getattr(
            coro, '__qualname__',
            getattr(coro, '__name__', type(coro).__name__))
        coro_name = f'{coro_name}()'

        running = False
        try:
            running = coro.cr_running
        except AttributeError:
            try:
                running = coro.gi_running
            except AttributeError:
                pass

        if running:
            return f'{coro_name} running'
        else:
            return coro_name

    coro_name = None
    if isinstance(coro, CoroWrapper):
        func = coro.func
        coro_name = coro.__qualname__
        if coro_name is not None:
            coro_name = f'{coro_name}()'
    else:
        func = coro

    if coro_name is None:
        coro_name = format_helpers._format_callback(func, (), {})

    try:
        coro_code = coro.gi_code
    except AttributeError:
        coro_code = coro.cr_code

    try:
        coro_frame = coro.gi_frame
    except AttributeError:
        coro_frame = coro.cr_frame

    filename = coro_code.co_filename
    lineno = 0
    if (isinstance(coro, CoroWrapper) and
            not inspect.isgeneratorfunction(coro.func) and
            coro.func is not None):
        source = format_helpers._get_function_source(coro.func)
        if source is not None:
            filename, lineno = source
        if coro_frame is None:
            coro_repr = f'{coro_name} done, defined at {filename}:{lineno}'
        else:
            coro_repr = f'{coro_name} running, defined at {filename}:{lineno}'
    elif coro_frame is not None:
        lineno = coro_frame.f_lineno
        coro_repr = f'{coro_name} running at {filename}:{lineno}'
    else:
        lineno = coro_code.co_firstlineno
        coro_repr = f'{coro_name} done, defined at {filename}:{lineno}'

    return coro_repr
Пример #51
0
# generator02
# 参考:http://python.jobbole.com/84527/

# def container(start, end):
# 	while start < end:
# 		print (start)
# 		start += 1
from inspect import isgeneratorfunction


def container(start, end):
    while start < end:
        yield start  # 用于 创建 生成器generator
        start += 1


c = container(0, 59999999999999999999999999999)

print(isgeneratorfunction(container))
print(type(c))
print(c)  #  0,1,2,3,4
print(next(c))  # 01,2
# for i in c:
#     print(i)  #StopIteration
Пример #52
0
def log(function=None, sensitives=None, customs=None, single_values=False):
    '''Log decorator to be used with
	:func:`simple_response`::

		@simple_response
		@log
		def my_func(self, var1, var2):
			return "%s__%s" % (var1, var2)

	The above example will write two lines into the logfile for the
	module (given that the the UCR variable *umc/module/debug/level*
	is set to at least 3)::

		<date>  MODULE      ( INFO    ) : my_func got: var1='value1', var2='value2'
		<date>  MODULE      ( INFO    ) : my_func returned: 'value1__value2'

	The variable names are ordered by appearance and hold the values that
	are actually going to be passed to the function (i.e. after they were
	:func:`sanitize` 'd or set to their default value).
	You may specify the names of sensitive arguments that should not
	show up in log files and custom functions that can alter the
	representation of a certain variable's values (useful for non-standard
	datatypes like regular expressions - you may have used a
	:class:`~univention.management.console.modules.sanitizers.PatternSanitizer`
	)::

		@sanitize(pattern=PatternSanitizer())
		@simple_reponse
		@log(sensitives=['password'], customs={'pattern':lambda x: x.pattern})
		def count_ucr(self, username, password, pattern):
			return self._ucr_count(username, password, pattern)

	This results in something like::

		<date>  MODULE      ( INFO    ) : count_ucr got: password='******', username='******', pattern='.*'
		<date>  MODULE      ( INFO    ) : count_ucr returned: 650

	The decorator also works with :func:`multi_response`::

		@multi_response
		@log
		def multi_my_func(self, var1, var2):
			return "%s__%s" % (var1, var2)

	This results in something like::

		<date>  MODULE      ( INFO    ) : multi_my_func got: [var1='value1', var2='value2'], [var1='value3', var2='value4']
		<date>  MODULE      ( INFO    ) : multi_my_func returned: ['value1__value2', 'value3__value4']
	'''
    if function is None:
        return lambda f: log(f, sensitives, customs, single_values)
    if customs is None:
        customs = {}
    if sensitives is None:
        sensitives = []
    for sensitive in sensitives:
        customs[sensitive] = lambda x: '********'

    def _log(names, args):
        if single_values:
            args = [args]
        return [
            '%s=%r' % (name, customs.get(name, lambda x: x)(arg))
            for name, arg in zip(names, args)
        ]

    # including self
    names, _ = arginspect(function)
    name = function.__name__
    # multi_response yields i.e. is generator function
    if inspect.isgeneratorfunction(function):
        # remove self, iterator
        names = names[2:]

        def _response(self, iterator, *args):
            arg_reprs = []
            for element in iterator:
                arg_repr = _log(names, element)
                if arg_repr:
                    arg_reprs.append(arg_repr)
            if arg_reprs:
                MODULE.info('%s got: [%s]' %
                            (name, '], ['.join(', '.join(arg_repr)
                                               for arg_repr in arg_reprs)))
            result = []
            for res in function(self, iterator, *args):
                result.append(res)
                yield res
            MODULE.info('%s returned: %r' % (name, result))
    else:
        # remove self
        names = names[1:]

        def _response(self, *args):
            arg_repr = _log(names, args)
            if arg_repr:
                MODULE.info('%s got: %s' % (name, ', '.join(arg_repr)))
            result = function(self, *args)
            MODULE.info('%s returned: %r' % (name, result))
            return result

    copy_function_meta_data(function, _response, copy_arg_inspect=True)
    return _response
Пример #53
0
def is_generator(obj):
    """Return True if ``obj`` is a generator
    """
    return inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj)
Пример #54
0
    def add_route(self,
                  method,
                  path,
                  handler,
                  *,
                  name=None,
                  expect_handler=None):

        if not path.startswith('/'):
            raise ValueError("path should be started with /")

        assert callable(handler), handler
        if asyncio.iscoroutinefunction(handler):
            pass
        elif inspect.isgeneratorfunction(handler):
            pass
        elif isinstance(handler, type) and issubclass(handler, AbstractView):
            pass
        else:
            handler = asyncio.coroutine(handler)

        method = upstr(method)
        if method not in self.METHODS:
            raise ValueError("{} is not allowed HTTP method".format(method))

        if not ('{' in path or '}' in path or self.ROUTE_RE.search(path)):
            route = PlainRoute(method,
                               handler,
                               name,
                               path,
                               expect_handler=expect_handler)
            self.register_route(route)
            return route

        pattern = ''
        formatter = ''
        for part in self.ROUTE_RE.split(path):
            match = self.DYN.match(part)
            if match:
                pattern += '(?P<{}>{})'.format(match.group('var'), self.GOOD)
                formatter += '{' + match.group('var') + '}'
                continue

            match = self.DYN_WITH_RE.match(part)
            if match:
                pattern += '(?P<{var}>{re})'.format(**match.groupdict())
                formatter += '{' + match.group('var') + '}'
                continue

            if '{' in part or '}' in part:
                raise ValueError("Invalid path '{}'['{}']".format(path, part))

            formatter += part
            pattern += re.escape(part)

        try:
            compiled = re.compile('^' + pattern + '$')
        except re.error as exc:
            raise ValueError("Bad pattern '{}': {}".format(pattern,
                                                           exc)) from None
        route = DynamicRoute(method,
                             handler,
                             name,
                             compiled,
                             formatter,
                             expect_handler=expect_handler)
        self.register_route(route)
        return route
Пример #55
0
    def _execute_and_send(self, cmd, args, match, msg, template_name=None):
        """Execute a bot command and send output back to the caller

        :param cmd: The command that was given to the bot (after being expanded)
        :param args: Arguments given along with cmd
        :param match: A re.MatchObject if command is coming from a regex-based command, else None
        :param msg: The message object
        :param template_name: The name of the jinja template which should be used to render
            the markdown output, if any

        """
        private = cmd in self.bot_config.DIVERT_TO_PRIVATE
        threaded = cmd in self.bot_config.DIVERT_TO_THREAD
        commands = self.re_commands if match else self.commands
        try:
            with self._gbl:
                method = commands[cmd]
            # first check if we need to reattach a flow context
            flow, _ = self.flow_executor.check_inflight_flow_triggered(
                cmd, msg.frm)
            if flow:
                log.debug("Reattach context from flow %s to the message",
                          flow._root.name)
                msg.ctx = flow.ctx
            elif method._err_command_flow_only:
                # check if it is a flow_only command but we are not in a flow.
                log.debug(
                    "%s is tagged flow_only and we are not in a flow. Ignores the command.",
                    cmd,
                )
                return

            if inspect.isgeneratorfunction(method):
                replies = method(msg, match) if match else method(msg, args)
                for reply in replies:
                    if reply:
                        self.send_simple_reply(
                            msg,
                            self.process_template(template_name, reply),
                            private,
                            threaded,
                        )
            else:
                reply = method(msg, match) if match else method(msg, args)
                if reply:
                    self.send_simple_reply(
                        msg,
                        self.process_template(template_name, reply),
                        private,
                        threaded,
                    )

            # The command is a success, check if this has not made a flow progressed
            self.flow_executor.trigger(cmd, msg.frm, msg.ctx)

        except CommandError as command_error:
            reason = command_error.reason
            if command_error.template:
                reason = self.process_template(command_error.template, reason)
            self.send_simple_reply(msg, reason, private, threaded)

        except Exception as e:
            tb = traceback.format_exc()
            log.exception(
                f'An error happened while processing a message ("{msg.body}"): {tb}"'
            )
            self.send_simple_reply(msg, self.MSG_ERROR_OCCURRED + f":\n{e}",
                                   private, threaded)
Пример #56
0
    def traversal_apply(self,
                        func,
                        filter_fn=lambda x: x is not None,
                        order='pre',
                        first='depth'):
        if order.lower() not in ['pre', 'post']:
            raise ValueError(
                'Options for order are pre or post, {} given.'.format(order))
        if first.lower() not in ['depth', 'breadth']:
            raise ValueError(
                'Options for first are depth or breadth, {} given.'.format(
                    first))

        to_traversal = [
            self,
        ]
        to_apply = []

        while to_traversal:
            if first.lower() == 'depth':
                current = to_traversal.pop()
            else:
                current = to_traversal.pop(0)
            to_apply.append(current)

            if order.lower() == 'pre':
                current_apply = to_apply.pop()
                if inspect.isgeneratorfunction(func):
                    # func: yield
                    if filter_fn:
                        yield from filter(filter_fn, func(current_apply))
                    else:
                        yield from func(current_apply)
                else:
                    # func: return
                    retval = func(current_apply)
                    if not filter_fn or filter_fn(retval):
                        yield retval

            if isinstance(current, NamedTree):
                subs = [
                    current[name] for name in current
                ]  # compatible to subclasses that override the iterator
                if (first.lower() == 'depth' and order.lower()
                        == 'pre') or (first.lower() == 'breadth'
                                      and order.lower() == 'post'):
                    subs = reversed(subs)

                to_traversal.extend(subs)

        if order.lower() == 'post':
            while to_apply:
                current_apply = to_apply.pop()
                if inspect.isgeneratorfunction(func):
                    # func: yield
                    if filter_fn:
                        yield from filter(filter_fn, func(current_apply))
                    else:
                        yield from func(current_apply)
                else:
                    # func: return
                    retval = func(current_apply)
                    if not filter_fn or filter_fn(retval):
                        yield retval
Пример #57
0
def _is_coroutine(obj):
    """Check to see if an object is really an asyncio coroutine."""
    return asyncio.iscoroutinefunction(obj) or inspect.isgeneratorfunction(obj)
Пример #58
0
def isgeneratorfunction(object):  # pylint: disable=redefined-builtin
    """TFDecorator-aware replacement for inspect.isgeneratorfunction."""
    return _inspect.isgeneratorfunction(
        tf.__internal__.decorator.unwrap(object)[1])
Пример #59
0
def is_generator(func):
    genfunc = inspect.isgeneratorfunction(func)
    return genfunc and not iscoroutinefunction(func)
Пример #60
0
def _format_coroutine(coro):
    assert iscoroutine(coro)

    if not hasattr(coro, 'cr_code') and not hasattr(coro, 'gi_code'):
        # Most likely a Cython coroutine.
        coro_name = getattr(coro, '__qualname__', coro.__name__)
        coro_name = '{}()'.format(coro_name)

        running = False
        try:
            running = coro.cr_running
        except AttributeError:
            try:
                running = coro.gi_running
            except AttributeError:
                pass

        if running:
            return '{} running'.format(coro_name)
        else:
            return coro_name

    coro_name = None
    if isinstance(coro, CoroWrapper):
        func = coro.func
        coro_name = coro.__qualname__
        if coro_name is not None:
            coro_name = '{}()'.format(coro_name)
    else:
        func = coro

    if coro_name is None:
        coro_name = events._format_callback(func, (), {})

    try:
        coro_code = coro.gi_code
    except AttributeError:
        coro_code = coro.cr_code

    try:
        coro_frame = coro.gi_frame
    except AttributeError:
        coro_frame = coro.cr_frame

    filename = coro_code.co_filename
    lineno = 0
    if (isinstance(coro, CoroWrapper)
            and not inspect.isgeneratorfunction(coro.func)
            and coro.func is not None):
        source = events._get_function_source(coro.func)
        if source is not None:
            filename, lineno = source
        if coro_frame is None:
            coro_repr = ('%s done, defined at %s:%s' %
                         (coro_name, filename, lineno))
        else:
            coro_repr = ('%s running, defined at %s:%s' %
                         (coro_name, filename, lineno))
    elif coro_frame is not None:
        lineno = coro_frame.f_lineno
        coro_repr = ('%s running at %s:%s' % (coro_name, filename, lineno))
    else:
        lineno = coro_code.co_firstlineno
        coro_repr = ('%s done, defined at %s:%s' %
                     (coro_name, filename, lineno))

    return coro_repr