async def test_ensure_awaitable(): m = AsyncMock() def test(): return m a = utils.ensure_awaitable(test) assert inspect.isawaitable(a) await a m.assert_called_once_with() m = AsyncMock() async def test(): return await m a = utils.ensure_awaitable(test) assert inspect.isawaitable(a) await a m.assert_called_once_with() m = AsyncMock() async def test(): return await m a = utils.ensure_awaitable(test()) assert inspect.isawaitable(a) await a m.assert_called_once_with() with pytest.raises(TypeError): a = utils.ensure_awaitable("test()")
async def request_resource(self, type: Union[str, type], alias: str = 'default', *, timeout: Union[int, None] = None): """ Request a resource matching the given type and alias. If no such resource was found, this method will wait ``timeout`` seconds for it to become available. The timeout does not apply to resolving awaitables created by lazy resource creators. :param type: type of the requested resource :param alias: alias of the requested resource :param timeout: the timeout (in seconds; omit to use the context's default timeout) :return: the value contained by the requested resource (**NOT** a :class:`Resource` instance) :raises asphalt.core.context.ResourceNotFound: if the requested resource does not become available in the allotted time """ assert check_argument_types() if not type: raise ValueError('type must be a type or a nonempty string') if not alias: raise ValueError('alias must be a nonempty string') resource_type = qualified_name(type) if not isinstance(type, str) else type timeout = timeout if timeout is not None else self.default_timeout assert timeout >= 0, 'timeout must be a positive integer' # Build a context chain from this context and its parents context_chain = [self] while context_chain[-1]._parent: context_chain.append(context_chain[-1]._parent) # First try to look up the resource in the context chain for ctx in context_chain: resource = ctx._resources.get(resource_type, {}).get(alias) if resource is not None: value = resource.get_value(self) return await value if isawaitable(value) else value # Listen to resource publish events in the whole chain and wait for the right kind of # resource to be published def resource_listener(event: ResourceEvent): if event.resource.alias == alias and resource_type in event.resource.types: future.set_result(event.resource) future = Future() for ctx in context_chain: ctx.resource_published.connect(resource_listener) try: resource = await wait_for(future, timeout) except TimeoutError: raise ResourceNotFound(resource_type, alias) from None else: value = resource.get_value(self) return await value if isawaitable(value) else value finally: for ctx in context_chain: ctx.resource_published.disconnect(resource_listener)
async def resolve(self, _next, _resource, _info, **kwargs): parent_name = _info.parent_type.name field_name = _info.field_name return_type = _info.return_type self.logger.log( self.level, f'Resolving {parent_name}.{field_name} expecting type {return_type}' ) start_time = time.perf_counter() if inspect.isawaitable(_next): results = await _next(_resource, _info, **kwargs) else: results = _next(_resource, _info, **kwargs) if inspect.isawaitable(results): results = await results end_time = time.perf_counter() total_time = end_time - start_time self.logger.log( self.level, f'Field {parent_name}.{field_name} resolved: {results!r} in {total_time:.6f} seconds' ) return results
def test_convert_generator_to_coroutine(): def gen(): yield 100 assert not inspect.isawaitable(gen()) coroutine(gen) assert inspect.isawaitable(gen())
async def save(self, force_insert=False, only=None): result = super().save(force_insert=force_insert, only=only) if self._meta.primary_key is not False: pk_value = self._get_pk_value() if inspect.isawaitable(pk_value): self._set_pk_value(await pk_value) if inspect.isawaitable(result): return await result return result
async def run_it(self, _next, _resource, _info, **kwargs): if inspect.isawaitable(_next): results = await _next(_resource, _info, **kwargs) else: results = _next(_resource, _info, **kwargs) if inspect.isawaitable(results): return await results return results
def test_Awaitable(self): def gen(): yield #@types.coroutine #def coro(): # yield #async def new_coro(): # pass class Bar(object): def __await__(self): yield class MinimalCoro(Coroutine): def send(self, value): return value def throw(self, typ, val=None, tb=None): super(MinimalCoro, self).throw(typ, val, tb) def __await__(self): yield non_samples = [None, int(), gen(), object()] for x in non_samples: self.assertNotIsInstance(x, Awaitable) self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) self.assertFalse(inspect.isawaitable(x)) samples = [Bar(), MinimalCoro()] for x in samples: self.assertIsInstance(x, Awaitable) self.assertTrue(issubclass(type(x), Awaitable)) self.assertTrue(inspect.isawaitable(x)) #c = coro() #self.assertIsInstance(c, Awaitable) #c.close() # awoid RuntimeWarning that coro() was not awaited #c = new_coro() #self.assertIsInstance(c, Awaitable) #c.close() # awoid RuntimeWarning that coro() was not awaited class CoroLike(object): pass Coroutine.register(CoroLike) self.assertTrue(inspect.isawaitable(CoroLike())) self.assertTrue(isinstance(CoroLike(), Awaitable)) self.assertTrue(issubclass(CoroLike, Awaitable)) CoroLike = None gc_collect() # Kill CoroLike to clean-up ABCMeta cache
async def _eval(self, ctx, *, code: str): """Extremely unsafe eval command. Stolen from someone, Unknown original author""" code = code.strip('` ') python = '```py\n{}\n```' env = { 'bot': self.bot, 'ctx': ctx, 'message': ctx.message, 'guild': ctx.guild, 'channel': ctx.channel, 'author': ctx.author } env.update(globals()) try: result = eval(code, env) if inspect.isawaitable(result): result = await result except Exception as e: await ctx.send(python.format(type(e).__name__ + ': ' + str(e))) return await ctx.send(python.format(result))
async def debug(self, ctx, *, code : str): """Evaluates code.""" code = code.strip('` ') python = '```py\n{}\n```' result = None env = { 'bot': self.bot, 'ctx': ctx, 'message': ctx.message, 'server': ctx.message.server, 'channel': ctx.message.channel, 'author': ctx.message.author } env.update(globals()) try: result = eval(code, env) if inspect.isawaitable(result): result = await result except Exception as e: await self.bot.say(python.format(type(e).__name__ + ': ' + str(e))) return try: await self.bot.say(python.format(result)) except discord.HTTPException: await self.bot.say("Result is too long for me to send") except: pass
async def run_eval(self, code, ctx): vals = globals() vals.update(dict( bot=self, message=ctx.message, ctx=ctx, guild=ctx.guild, channel=ctx.channel, author=ctx.author, code=code )) try: precompiled = compile(code, "<eval>", "eval") vals["compiled"] = precompiled result = eval(precompiled, vals) except SyntaxError as e: return f"```py\n{e.text}\n{'^':>{e.offset}}\n{type(e).__name__}: {e}\n```" except Exception as e: return f"```diff\n- {type(e).__name__}: {e}\n```" if isawaitable(result): result = await result result = str(result) if len(result) > 1900: gist = await self.upload_to_gist(result, "eval.py") return f"\N{WARNING SIGN} Output too long. View result at {gist}\n" else: return f"```py\n{result}\n```"
async def close(self, exception: BaseException = None) -> None: """ Close this context and call any necessary resource teardown callbacks. If a teardown callback returns an awaitable, the return value is awaited on before calling any further teardown callbacks. All callbacks will be processed, even if some of them raise exceptions. If at least one callback raised an error, this method will raise a :exc:`~.TeardownError` at the end. After this method has been called, resources can no longer be requested or published on this context. :param exception: the exception, if any, that caused this context to be closed :raises .TeardownError: if one or more teardown callbacks raise an exception """ self._check_closed() self._closed = True exceptions = [] for callback, pass_exception in reversed(self._teardown_callbacks): try: retval = callback(exception) if pass_exception else callback() if isawaitable(retval): await retval except Exception as e: exceptions.append(e) del self._teardown_callbacks if exceptions: raise TeardownError(exceptions)
def emit(self, record): """Emit record to slack channel using pycurl to avoid recurrence event logging (log logged record) """ if record.message.startswith(MESSAGE): # avoid cyrcular emit return cfg = self.app.config managers = cfg['SLACK_LINK_NAMES'] text = '' data = {} if managers: text = ' '.join(('@%s' % m for m in managers)) text = '%s\n\n' % text data['link_names'] = 1 context_factory = cfg['LOG_CONTEXT_FACTORY'] data['text'] = text if context_factory: ctx = context_factory(self) data['text'] += "\n" + context_text_formatter(ctx) data['text'] += "```\n%s\n```" % self.format(record) sessions = self.app.http() response = sessions.post(self.webhook_url, data=json.dumps(data)) if isawaitable(response): ensure_future(self._emit(response), loop=sessions._loop) else: sessions._loop.call_soon(self._raise_error, response)
async def request(url, *, headers=None, payload=None, method='GET', attr='json'): # Make sure our User Agent is what's set, and ensure it's sent even if no headers are passed if headers == None: headers = {} headers['User-Agent'] = config.user_agent # Try 5 times for i in range(5): try: # Create the session with our headeres with aiohttp.ClientSession(headers=headers) as session: # Make the request, based on the method, url, and paramaters given async with session.request(method, url, params=payload) as response: # If the request wasn't successful, re-attempt if response.status != 200: continue try: # Get the attribute requested return_value = getattr(response, attr) # Next check if this can be called if callable(return_value): return_value = return_value() # If this is awaitable, await it if inspect.isawaitable(return_value): return_value = await return_value # Then return it return return_value except AttributeError: # If an invalid attribute was requested, return None return None # If an error was hit other than the one we want to catch, try again except: continue
async def do_dispatch(): futures, exceptions = [], [] for callback in listeners: try: retval = callback(event) except Exception as e: exceptions.append((callback, e)) if not return_future: logger.exception('uncaught exception in event listener') else: if isawaitable(retval): if iscoroutine(retval): retval = loop.create_task(retval) futures.append((callback, retval)) # For any callbacks that returned awaitables, wait for their completion and collect any # exceptions they raise for callback, awaitable in futures: try: await awaitable except Exception as e: exceptions.append((callback, e)) if not return_future: logger.exception('uncaught exception in event listener') if exceptions and return_future: raise EventDispatchError(event, exceptions)
def convert_yielded(yielded: _Yieldable) -> Future: """Convert a yielded object into a `.Future`. The default implementation accepts lists, dictionaries, and Futures. If the `~functools.singledispatch` library is available, this function may be extended to support additional types. For example:: @convert_yielded.register(asyncio.Future) def _(asyncio_future): return tornado.platform.asyncio.to_tornado_future(asyncio_future) .. versionadded:: 4.1 """ if yielded is None or yielded is moment: return moment elif yielded is _null_future: return _null_future elif isinstance(yielded, (list, dict)): return multi(yielded) # type: ignore elif is_future(yielded): return typing.cast(Future, yielded) elif isawaitable(yielded): return _wrap_awaitable(yielded) # type: ignore else: raise BadYieldError("yielded unknown object %r" % (yielded,))
async def debug(self, ctx, *, code : str): print("OK") """Evaluates code.""" code = code.strip('` ') python = '```py\n{}\n```' result = None env = { 'bot': self.bot, 'ctx': ctx, 'message': ctx.message, 'guild': ctx.message.guild, 'channel': ctx.message.channel, 'author': ctx.message.author, 'redis': utils.redis } env.update(globals()) try: result = eval(code, env) if inspect.isawaitable(result): result = await result except Exception as e: await ctx.send(python.format(type(e).__name__ + ': ' + str(e))) return if len(python.format(result)) >= 2000: msg = await utils.send_hastebin(python.format(result)) else: msg = python.format(result) await ctx.send(msg)
async def _call(self): testMethod = self.testMethod testStartUp = getattr(self.test, 'startUp', lambda: None) testGetTime = getattr(self.test, 'getTime', lambda dt: dt) testGetInfo = getattr(self.test, 'getInfo', simple) testGetSummary = getattr(self.test, 'getSummary', simple) t = 0 t2 = 0 info = {'name': '%s.%s' % (self.test.__class__.__name__, testMethod.__name__)} for r in range(self.repeat): DT = 0 for r in range(self.number): testStartUp() start = default_timer() result = testMethod() if isawaitable(result): await result delta = default_timer() - start dt = testGetTime(delta) testGetInfo(info, delta, dt) DT += dt t += DT t2 += DT*DT self.update_summary(info, self.repeat, t, t2) self.set_test_attribute('bench_info', testGetSummary(info, self.repeat, t, t2))
async def _run_safe(self, test, method_name, test_timeout, error=None): exc = None self._check_abort() try: method = getattr(test, method_name) coro = method() # a coroutine if isawaitable(coro): test_timeout = get_test_timeout(method, test_timeout) with timeout(self._loop, test_timeout): exc = await store_trace(coro) elif isgenerator(coro): raise InvalidTestFunction('test function returns a generator') except SkipTest as x: self.runner.addSkip(test, str(x)) exc = None error = False except Exception as x: exc = TestFailure(x) if exc and not error: error = exc can_fail = allow_failure(method) or expecting_failure(method) self.add_failure(test, error, can_fail) return error
async def debug(self, ctx, *, code: str): """Lets the bot owner evaluate code.""" code = code.strip('` ') python = '```py\n{}\n```' result = None env = { 'bot': self.bot, 'ctx': ctx, 'message': ctx.message, 'server': ctx.message.server, 'channel': ctx.message.channel, 'author': ctx.message.author } env.update(globals()) try: result = eval(code, env) if inspect.isawaitable(result): result = await result except Exception as e: await self.bot.say(python.format(type(e).__name__ + ': ' + str(e))) return await self.bot.say(python.format(result))
def main(): print('-' * 80) print(str.format( '[*] coroutine is coroutine function => {}', inspect.iscoroutinefunction(coroutine) )) print(str.format( '[*] subcoroutine is coroutine function => {}', inspect.iscoroutinefunction(subcoroutine) )) sub1 = subcoroutine('Subroutine') print(str.format( '[*] sub1 is coroutine object => {}', inspect.iscoroutine(sub1) )) coro1 = coroutine('Coroutine') print(str.format( '[*] coro1 is coroutine object => {}', inspect.iscoroutine(coro1) )) print('-' * 80) print(str.format( '[*] CoroutineClass is sub-class of Awaitable class => {}', issubclass(CoroutineClass, Awaitable) )) c1 = CoroutineClass('Coroutine #1', ['A', 'B', 'C']) print(str.format( '[*] c1 is awaitable object => {}', inspect.isawaitable(c1) )) print(str.format( '[*] c1 is instance of Awaitable class => {}', isinstance(c1, Awaitable) )) print('-' * 80)
async def call( self, document: GraphQLSchema, request: typing.Any = None, variables: typing.Dict[str, typing.Any] = None ) -> ExecutionResult: """Preform a query against the schema. This is meant to be called in an asyncio.loop, if you are using a web framework that is synchronous use the `call_sync` method. """ validation_errors = validate(self.schema, document) if validation_errors: return ExecutionResult(data=None, errors=validation_errors) context = self.get_context(request) result = execute( schema=self.schema, document=document, context_value=context, variable_values=variables, middleware=self.middleware, ) if inspect.isawaitable(result): return await result return result
def maybe_future(obj): """Return an asyncio Future Use instead of gen.maybe_future For our compatibility, this must accept: - asyncio coroutine (gen.maybe_future doesn't work in tornado < 5) - tornado coroutine (asyncio.ensure_future doesn't work) - scalar (asyncio.ensure_future doesn't work) - concurrent.futures.Future (asyncio.ensure_future doesn't work) - tornado Future (works both ways) - asyncio Future (works both ways) """ if inspect.isawaitable(obj): # already awaitable, use ensure_future return asyncio.ensure_future(obj) elif isinstance(obj, concurrent.futures.Future): return asyncio.wrap_future(obj) else: # could also check for tornado.concurrent.Future # but with tornado >= 5 tornado.Future is asyncio.Future f = asyncio.Future() f.set_result(obj) return f
def ensure_iterables(*iterables, loop=None): for iterable in iterables: if inspect.isawaitable(iterable): future = asyncio.ensure_future(iterable, loop=loop) yield future_iterator(future) else: yield iterable
async def process_function(self, function, *args): arg_list = [self.arg_cache.popleft() if not isinstance(arg, lexer.Token) else arg.source.strip() for arg in args] arg_names = ["EXTERNAL" + str(self.level) if not isinstance(arg, lexer.Token) else arg.name for arg in args] func_name = function.source if KEYWORD_REGEX.fullmatch(func_name) is None: raise InvalidFunctionNameError("Function names must be alphanumeric") self.log(f"[Process] Calling {func_name} with args {list(zip(arg_names, arg_list))}") if hasattr(self.tag_functions, func_name): if callable(getattr(self.tag_functions, func_name)): try: func_result = getattr(self.tag_functions, func_name)(*arg_list) if isawaitable(func_result): func_result = await func_result return "" if func_result is None else func_result except Exception as e: return str(e) if self.tag_functions.fallback_text is None else str(self.tag_functions.fallback_text) else: raise ParserError("An error occurred.") else: raise NonExistantFunctionError(f"Function {func_name} doesn't exist")
def _as_future(obj, loop): if inspect.isawaitable(obj): return asyncio.ensure_future(obj, loop=loop) f = loop.create_future() f.set_result(obj) return f
def convert_yielded(yielded): """Convert a yielded object into a `.Future`. The default implementation accepts lists, dictionaries, and Futures. If the `~functools.singledispatch` library is available, this function may be extended to support additional types. For example:: @convert_yielded.register(asyncio.Future) def _(asyncio_future): return tornado.platform.asyncio.to_tornado_future(asyncio_future) .. versionadded:: 4.1 """ # Lists and dicts containing YieldPoints were handled earlier. if yielded is None: return moment elif isinstance(yielded, (list, dict)): return multi(yielded) elif is_future(yielded): return yielded elif isawaitable(yielded): return _wrap_awaitable(yielded) else: raise BadYieldError("yielded unknown object %r" % (yielded,))
def begin_request(self): ctx = HTTPRequestResponseContext(self.parent_ctx, self.request) try: retval = self.func(ctx) if isawaitable(retval): ensure_future(retval).add_done_callback(self.process_return_value) except Exception as e: pass
def close(self): self.closed = True # there is no reason for sess.close to be a coroutine, and # in older versions of aiohttp, it isn't. In newer versions # close returns an awaitable whose only purpose is to warn you # if you don't await it, so... await it... I guess??? aiohttp_is_silly = self.sess.close() if inspect.isawaitable(aiohttp_is_silly): asyncio.ensure_future(aiohttp_is_silly)
async def trigger_events(self, events, loop): """Trigger events (functions or async) :param events: one or more sync or async functions to execute :param loop: event loop """ for event in events: result = event(loop) if isawaitable(result): await result
async def coro_wrapper(proc, *a, **kw): """\ This code is responsible for turning whatever callable you pass in into a "yield from"-style coroutine. """ proc = proc(*a, **kw) if inspect.isawaitable(proc): proc = await proc return proc
async def await_and_set_result(results, response_name, result): awaited_results = await results awaited_results[response_name] = ( await result if isawaitable(result) else result) return awaited_results
async def await_result(): value = self.complete_value(return_type, field_nodes, info, path, await result) if isawaitable(value): return await value return value
def declines_a_dict_value(): assert not isawaitable({}) assert not is_awaitable({})
async def upload_file(self: 'TelegramClient', file: 'hints.FileLike', *, part_size_kb: float = None, file_name: str = None, use_cache: type = None, progress_callback: 'hints.ProgressCallback' = None, file_size=None, http_headers=None) -> 'types.TypeInputFile': """ Uploads a file to Telegram's servers, without sending it. This method returns a handle (an instance of :tl:`InputFile` or :tl:`InputFileBig`, as required) which can be later used before it expires (they are usable during less than a day). Uploading a file will simply return a "handle" to the file stored remotely in the Telegram servers, which can be later used on. This will **not** upload the file to your own chat or any chat at all. Arguments file (`str` | `bytes` | `file`): The path of the file, byte array, or stream that will be sent. Note that if a byte array or a stream is given, a filename or its type won't be inferred, and it will be sent as an "unnamed application/octet-stream". part_size_kb (`int`, optional): Chunk size when uploading files. The larger, the less requests will be made (up to 512KB maximum). file_name (`str`, optional): The file name which will be used on the resulting InputFile. If not specified, the name will be taken from the ``file`` and if this is not a `str`, it will be ``"unnamed"``. use_cache (`type`, optional): This parameter currently does nothing, but is kept for backward-compatibility (and it may get its use back in the future). progress_callback (`callable`, optional): A callback function accepting two parameters: ``(sent bytes, total)``. Returns :tl:`InputFileBig` if the file size is larger than 10MB, `InputSizedFile <telethon.tl.custom.inputsizedfile.InputSizedFile>` (subclass of :tl:`InputFile`) otherwise. Example .. code-block:: python # Photos as photo and document file = await client.upload_file('photo.jpg') await client.send_file(chat, file) # sends as photo await client.send_file(chat, file, force_document=True) # sends as document file.name = 'not a photo.jpg' await client.send_file(chat, file, force_document=True) # document, new name # As song or as voice note file = await client.upload_file('song.ogg') await client.send_file(chat, file) # sends as song await client.send_file(chat, file, voice_note=True) # sends as voice note """ if isinstance(file, (types.InputFile, types.InputFileBig)): return file # Already uploaded if file_size is None: if isinstance(file, str): if os.path.isfile(file): file_size = os.path.getsize(file) else: stream = req.urlopen(file) file_size = int(stream.headers['Content-Length']) elif isinstance(file, bytes): file_size = len(file) elif hasattr(file, 'tell') and hasattr(file, 'read') and hasattr( file, 'seek'): # `aiofiles` shouldn't base `IOBase` because they change the # methods' definition. `seekable` would be `async` but since # we won't get to check that, there's no need to maybe-await. if isinstance(file, io.IOBase) and file.seekable(): pos = file.tell() else: pos = None # TODO Don't load the entire file in memory always data = file.read() if inspect.isawaitable(data): data = await data if pos is not None: file.seek(pos) if not isinstance(data, bytes): raise TypeError( 'file descriptor returned {}, not bytes (you must ' 'open the file in bytes mode)'.format(type(data))) file = data file_size = len(file) else: raise Exception('file size required for uploading') # File will now either be a string or bytes if not part_size_kb: part_size_kb = utils.get_appropriated_part_size(file_size) if part_size_kb > 512: raise ValueError('The part size must be less or equal to 512KB') part_size = int(part_size_kb * 1024) if part_size % 1024 != 0: raise ValueError('The part size must be evenly divisible by 1024') # Set a default file name if None was specified file_id = helpers.generate_random_long() if not file_name: if isinstance(file, str): file_name = os.path.basename(file) else: file_name = str(file_id) # If the file name lacks extension, add it if possible. # Else Telegram complains with `PHOTO_EXT_INVALID_ERROR` # even if the uploaded image is indeed a photo. if not os.path.splitext(file_name)[-1]: file_name += utils._get_extension(file) # Determine whether the file is too big (over 10MB) or not # Telegram does make a distinction between smaller or larger files is_large = file_size > 10 * 1024 * 1024 hash_md5 = hashlib.md5() if not is_large: # Calculate the MD5 hash before anything else. # As this needs to be done always for small files, # might as well do it before anything else and # check the cache. if isinstance(file, str) and os.path.isfile(file): with open(file, 'rb') as stream: file = stream.read() elif hasattr(file, 'read'): if inspect.iscoroutinefunction(file.read): file = await file.read() else: file = file.read() if inspect.isawaitable(file): file = await file elif isinstance(file, str): get_req = req.Request(file, method='GET', headers=http_headers) with req.urlopen(get_req) as resp: file = resp.read() hash_md5.update(file) part_count = (file_size + part_size - 1) // part_size self._log[__name__].info( 'Uploading file of %d bytes in %d chunks of %d', file_size, part_count, part_size) if isinstance(file, str) and os.path.isfile(file): stream = open(file, mode='rb') elif hasattr(file, 'read'): stream = file elif isinstance(file, bytes): stream = BytesIO(file) else: get_req = req.Request(file, method='GET', headers=http_headers) stream = req.urlopen(get_req) for part_index in range(part_count): # Read the file by in chunks of size part_size # part = out_proc.stdout.read(part_size) part = None if hasattr(stream, 'read'): if inspect.iscoroutinefunction(stream.read): part = await stream.read(part_size) else: part = stream.read(part_size) if inspect.isawaitable(part): part = await part else: raise Exception( "Failed read from stream, there aren't read attribute") # part = stream.read(part_size) if len(part) == 0: part_count = part_index break if len(part) != part_size and part_index != part_count - 1: part_count = part_index + 1 # The SavePartRequest is different depending on whether # the file is too large or not (over or less than 10MB) if is_large: request = functions.upload.SaveBigFilePartRequest( file_id, part_index, part_count, part) else: request = functions.upload.SaveFilePartRequest( file_id, part_index, part) result = await self(request) if result: self._log[__name__].debug('Uploaded %d/%d', part_index + 1, part_count) if progress_callback: r = progress_callback(stream.tell(), file_size) if inspect.isawaitable(r): await r else: raise RuntimeError( 'Failed to upload file part {}.'.format(part_index)) if is_large: return types.InputFileBig(file_id, part_count, file_name) else: return custom.InputSizedFile(file_id, part_count, file_name, md5=hash_md5, size=file_size)
async def resolve(self, next_: Resolver, parent: Any, info: GraphQLResolveInfo, **kwargs): result = next_(parent, info, **kwargs) if isawaitable(result): result = await result return result
async def subscribe( schema: GraphQLSchema, data: Any, *, context_value: Optional[Any] = None, root_value: Optional[RootValue] = None, debug: bool = False, introspection: bool = True, logger: Optional[str] = None, validation_rules: Optional[ValidationRules] = None, error_formatter: ErrorFormatter = format_error, **kwargs, ) -> SubscriptionResult: try: validate_data(data) query, variables, operation_name = ( data["query"], data.get("variables"), data.get("operationName"), ) document = parse_query(query) if callable(validation_rules): validation_rules = cast( Optional[Sequence[RuleType]], validation_rules(context_value, document, data), ) validation_errors = validate_query(schema, document, validation_rules, enable_introspection=introspection) if validation_errors: for error_ in validation_errors: # mypy issue #5080 log_error(error_, logger) return ( False, [error_formatter(error, debug) for error in validation_errors], ) if callable(root_value): root_value = root_value(context_value, document) if isawaitable(root_value): root_value = await root_value result = await _subscribe( schema, document, root_value=root_value, context_value=context_value, variable_values=variables, operation_name=operation_name, **kwargs, ) except GraphQLError as error: log_error(error, logger) return False, [error_formatter(error, debug)] else: if isinstance(result, ExecutionResult): errors = cast(List[GraphQLError], result.errors) for error_ in errors: # mypy issue #5080 log_error(error_, logger) return False, [error_formatter(error, debug) for error in errors] return True, cast(AsyncGenerator, result)
def declines_a_boolean_value(): assert not isawaitable(True) assert not is_awaitable(True)
async def edit_2fa( self: 'TelegramClient', current_password: str = None, new_password: str = None, *, hint: str = '', email: str = None, email_code_callback: typing.Callable[[int], str] = None) -> bool: """ Changes the 2FA settings of the logged in user. Review carefully the parameter explanations before using this method. Note that this method may be *incredibly* slow depending on the prime numbers that must be used during the process to make sure that everything is safe. Has no effect if both current and new password are omitted. Arguments current_password (`str`, optional): The current password, to authorize changing to ``new_password``. Must be set if changing existing 2FA settings. Must **not** be set if 2FA is currently disabled. Passing this by itself will remove 2FA (if correct). new_password (`str`, optional): The password to set as 2FA. If 2FA was already enabled, ``current_password`` **must** be set. Leaving this blank or `None` will remove the password. hint (`str`, optional): Hint to be displayed by Telegram when it asks for 2FA. Leaving unspecified is highly discouraged. Has no effect if ``new_password`` is not set. email (`str`, optional): Recovery and verification email. If present, you must also set `email_code_callback`, else it raises ``ValueError``. email_code_callback (`callable`, optional): If an email is provided, a callback that returns the code sent to it must also be set. This callback may be asynchronous. It should return a string with the code. The length of the code will be passed to the callback as an input parameter. If the callback returns an invalid code, it will raise ``CodeInvalidError``. Returns `True` if successful, `False` otherwise. Example .. code-block:: python # Setting a password for your account which didn't have await client.edit_2fa(new_password='******') # Removing the password await client.edit_2fa(current_password='******') """ if new_password is None and current_password is None: return False if email and not callable(email_code_callback): raise ValueError('email present without email_code_callback') pwd = await self(functions.account.GetPasswordRequest()) pwd.new_algo.salt1 += os.urandom(32) assert isinstance(pwd, types.account.Password) if not pwd.has_password and current_password: current_password = None if current_password: password = pwd_mod.compute_check(pwd, current_password) else: password = types.InputCheckPasswordEmpty() if new_password: new_password_hash = pwd_mod.compute_digest(pwd.new_algo, new_password) else: new_password_hash = b'' try: await self( functions.account.UpdatePasswordSettingsRequest( password=password, new_settings=types.account.PasswordInputSettings( new_algo=pwd.new_algo, new_password_hash=new_password_hash, hint=hint, email=email, new_secure_settings=None))) except errors.EmailUnconfirmedError as e: code = email_code_callback(e.code_length) if inspect.isawaitable(code): code = await code code = str(code) await self(functions.account.ConfirmPasswordEmailRequest(code)) return True
async def repl(self, ctx): """Launches an interactive REPL session.""" variables = { 'ctx': ctx, 'bot': self.bot, 'message': ctx.message, 'guild': ctx.guild, 'channel': ctx.channel, 'author': ctx.author, '_': None, } if ctx.channel.id in self.sessions: await ctx.send( 'Already running a REPL session in this channel. Exit it with `quit`.' ) return self.sessions.add(ctx.channel.id) await ctx.send( 'Enter code to execute or evaluate. `exit()` or `quit` to exit.') def check(m): return m.author.id == ctx.author.id and \ m.channel.id == ctx.channel.id and \ m.content.startswith('`') while True: try: response = await self.bot.wait_for('message', check=check, timeout=10.0 * 60.0) except asyncio.TimeoutError: await ctx.send('Exiting REPL session.') self.sessions.remove(ctx.channel.id) break cleaned = self.cleanup_code(response.content) if cleaned in ('quit', 'exit', 'exit()'): await ctx.send('Exiting.') self.sessions.remove(ctx.channel.id) return executor = exec if cleaned.count('\n') == 0: # single statement, potentially 'eval' try: code = compile(cleaned, '<repl session>', 'eval') except SyntaxError: pass else: executor = eval if executor is exec: try: code = compile(cleaned, '<repl session>', 'exec') except SyntaxError as e: await ctx.send(self.get_syntax_error(e)) continue variables['message'] = response fmt = None stdout = io.StringIO() try: with contextlib.redirect_stdout(stdout): result = executor(code, variables) if inspect.isawaitable(result): result = await result except Exception as e: value = stdout.getvalue() fmt = f'```py\n{value}{traceback.format_exc()}\n```' else: value = stdout.getvalue() if result is not None: fmt = f'```py\n{value}{result}\n```' variables['_'] = result elif value: fmt = f'```py\n{value}\n```' try: if fmt is not None: if len(fmt) > 2000: await ctx.send('Content too big to be printed.') else: await ctx.send(fmt) except discord.Forbidden: pass except discord.HTTPException as e: await ctx.send(f'Unexpected error: `{e}`')
def declines_a_coroutine_function(): async def some_coroutine(): return True # pragma: no cover assert not isawaitable(some_coroutine) assert not is_awaitable(some_coroutine)
def declines_a_normal_generator_object(): def some_generator(): yield True # pragma: no cover assert not isawaitable(some_generator()) assert not is_awaitable(some_generator())
def declines_a_normal_function(): def some_function(): return True assert not isawaitable(some_function()) assert not is_awaitable(some_function)
def declines_a_lambda_function(): assert not isawaitable(lambda: True) # pragma: no cover assert not is_awaitable(lambda: True) # pragma: no cover
def handleEndpointMessage(self, msg): body, frm = msg logger.debug("Message received (from -> {}): {}".format(frm, body)) if isinstance(frm, bytes): frm = frm.decode() for reqFieldName in (TYPE, f.REQ_ID.nm): reqFieldValue = body.get(reqFieldName) if not reqFieldValue: errorMsg = "{} not specified in message: {}".format( reqFieldName, body) self.notifyToRemoteCaller(EVENT_NOTIFY_MSG, errorMsg, self.wallet.defaultId, frm) logger.warning("{}".format(errorMsg)) return typ = body.get(TYPE) link = self.wallet.getLinkInvitationByTarget(body.get(f.IDENTIFIER.nm)) # If accept invite is coming the first time, then use the default # identifier of the wallet since link wont be created if typ == ACCEPT_INVITE and link is None: localIdr = self.wallet.defaultId else: # if accept invite is not the message type # and we are still missing link, then return the error if link is None: linkNotCreated = ' Error processing {}. ' \ 'Link is not yet created.'.format(typ) self.notifyToRemoteCaller(EVENT_NOTIFY_MSG, linkNotCreated, self.wallet.defaultId, frm) return localIdr = link.localIdentifier if typ in self.lockedMsgs: try: self.verifySignature(body) except SignatureRejected: self.sendSigVerifResponseMsg("\nSignature rejected.", frm, typ, localIdr) return reqId = body.get(f.REQ_ID.nm) oldResps = self.rcvdMsgStore.get(reqId) if oldResps: oldResps.append(msg) else: self.rcvdMsgStore[reqId] = [msg] # TODO: Question: Should we sending an acknowledgement for every message? # We are sending, ACKs for "signature accepted" messages too self.sendSigVerifResponseMsg("\nSignature accepted.", frm, typ, localIdr) handler = self.msgHandlers.get(typ) if handler: # TODO we should verify signature here frmHa = self.endpoint.getHa(frm) # `frmHa` can be None res = handler((body, (frm, frmHa))) if inspect.isawaitable(res): self.loop.call_soon(asyncio.ensure_future, res) else: raise NotImplementedError( "No type handle found for {} message".format(typ))
async def _process(self, msg: Any): result = self._process_sync(msg) return await result if isawaitable(result) else result
def declines_an_object_instance(): assert not isawaitable(object()) assert not is_awaitable(object())
async def _start(self: 'TelegramClient', phone, password, bot_token, force_sms, code_callback, first_name, last_name, max_attempts): if not self.is_connected(): await self.connect() # Rather than using `is_user_authorized`, use `get_me`. While this is # more expensive and needs to retrieve more data from the server, it # enables the library to warn users trying to login to a different # account. See #1172. me = await self.get_me() if me is not None: # The warnings here are on a best-effort and may fail. if bot_token: # bot_token's first part has the bot ID, but it may be invalid # so don't try to parse as int (instead cast our ID to string). if bot_token[:bot_token.find(':')] != str(me.id): warnings.warn( 'the session already had an authorized user so it did ' 'not login to the bot account using the provided ' 'bot_token (it may not be using the user you expect)') elif phone and not callable( phone) and utils.parse_phone(phone) != me.phone: warnings.warn( 'the session already had an authorized user so it did ' 'not login to the user account using the provided ' 'phone (it may not be using the user you expect)') return self if not bot_token: # Turn the callable into a valid phone number (or bot token) while callable(phone): value = phone() if inspect.isawaitable(value): value = await value if ':' in value: # Bot tokens have 'user_id:access_hash' format bot_token = value break phone = utils.parse_phone(value) or phone if bot_token: await self.sign_in(bot_token=bot_token) return self me = None attempts = 0 two_step_detected = False await self.send_code_request(phone, force_sms=force_sms) sign_up = False # assume login while attempts < max_attempts: try: value = code_callback() if inspect.isawaitable(value): value = await value # Since sign-in with no code works (it sends the code) # we must double-check that here. Else we'll assume we # logged in, and it will return None as the User. if not value: raise errors.PhoneCodeEmptyError(request=None) if sign_up: me = await self.sign_up(value, first_name, last_name) else: # Raises SessionPasswordNeededError if 2FA enabled me = await self.sign_in(phone, code=value) break except errors.SessionPasswordNeededError: two_step_detected = True break except errors.PhoneNumberOccupiedError: sign_up = False except errors.PhoneNumberUnoccupiedError: sign_up = True except (errors.PhoneCodeEmptyError, errors.PhoneCodeExpiredError, errors.PhoneCodeHashEmptyError, errors.PhoneCodeInvalidError): print('Invalid code. Please try again.', file=sys.stderr) attempts += 1 else: raise RuntimeError( '{} consecutive sign-in attempts failed. Aborting'.format( max_attempts)) if two_step_detected: if not password: raise ValueError( "Two-step verification is enabled for this account. " "Please provide the 'password' argument to 'start()'.") if callable(password): for _ in range(max_attempts): try: value = password() if inspect.isawaitable(value): value = await value me = await self.sign_in(phone=phone, password=value) break except errors.PasswordHashInvalidError: print('Invalid password. Please try again', file=sys.stderr) else: raise errors.PasswordHashInvalidError(request=None) else: me = await self.sign_in(phone=phone, password=password) # We won't reach here if any step failed (exit by exception) signed, name = 'Signed in successfully as', utils.get_display_name(me) try: print(signed, name) except UnicodeEncodeError: # Some terminals don't support certain characters print( signed, name.encode('utf-8', errors='ignore').decode('ascii', errors='ignore')) return self
async def repl(self, ctx, *, name: str = None): """Head on impact with an interactive python shell.""" # TODO Minimize local variables # TODO Minimize branches session = ctx.message.channel.id embed = discord.Embed( description="_Enter code to execute or evaluate. " "`exit()` or `quit` to exit._", timestamp=datetime.datetime.now()) embed.set_footer( text="Interactive Python Shell", icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb" "/c/c3/Python-logo-notext.svg/1024px-Python-logo-notext.svg.png") if name is not None: embed.title = name.strip(" ") history = collections.OrderedDict() variables = { 'ctx': ctx, 'bot': self.bot, 'message': ctx.message, 'server': ctx.message.guild, 'channel': ctx.message.channel, 'author': ctx.message.author, 'discord': discord, '_': None } if session in self.repl_sessions: error_embed = discord.Embed( color=15746887, description="**Error**: " "_Shell is already running in channel._") await ctx.send(embed=error_embed) return shell = await ctx.send(embed=embed) self.repl_sessions[session] = shell self.repl_embeds[shell] = embed while True: response = await self.bot.wait_for( 'message', check=lambda m: m.content.startswith('`') and m.author == ctx. author and m.channel == ctx.channel) cleaned = self._cleanup_code(response.content) shell = self.repl_sessions[session] # Regular Bot Method try: await ctx.message.channel.fetch_message( self.repl_sessions[session].id) except discord.NotFound: new_shell = await ctx.send(embed=self.repl_embeds[shell]) self.repl_sessions[session] = new_shell embed = self.repl_embeds[shell] del self.repl_embeds[shell] self.repl_embeds[new_shell] = embed shell = self.repl_sessions[session] try: await response.delete() except discord.Forbidden: pass if len(self.repl_embeds[shell].fields) >= 7: self.repl_embeds[shell].remove_field(0) if cleaned in ('quit', 'exit', 'exit()'): self.repl_embeds[shell].color = 16426522 if self.repl_embeds[shell].title is not discord.Embed.Empty: history_string = "History for {}\n\n\n".format( self.repl_embeds[shell].title) else: history_string = "History for latest session\n\n\n" for item in history.keys(): history_string += ">>> {}\n{}\n\n".format( item, history[item]) haste_url = await self.online.hastebin(history_string) return_msg = "[`Leaving shell session. "\ "History hosted on hastebin.`]({})".format( haste_url) self.repl_embeds[shell].add_field( name="`>>> {}`".format(cleaned), value=return_msg, inline=False) await self.repl_sessions[session].edit( embed=self.repl_embeds[shell]) del self.repl_embeds[shell] del self.repl_sessions[session] return executor = exec if cleaned.count('\n') == 0: # single statement, potentially 'eval' try: code = compile(cleaned, '<repl session>', 'eval') except SyntaxError: pass else: executor = eval if executor is exec: try: code = compile(cleaned, '<repl session>', 'exec') except SyntaxError as err: self.repl_embeds[shell].color = 15746887 return_msg = self._get_syntax_error(err) history[cleaned] = return_msg if len(cleaned) > 800: cleaned = "<Too big to be printed>" if len(return_msg) > 800: haste_url = await self.online.hastebin(return_msg) return_msg = "[`SyntaxError too big to be printed. "\ "Hosted on hastebin.`]({})".format( haste_url) self.repl_embeds[shell].add_field( name="`>>> {}`".format(cleaned), value=return_msg, inline=False) await self.repl_sessions[session].edit( embed=self.repl_embeds[shell]) continue variables['message'] = response fmt = None stdout = io.StringIO() try: with redirect_stdout(stdout): result = executor(code, variables) if inspect.isawaitable(result): result = await result except Exception as err: self.repl_embeds[shell].color = 15746887 value = stdout.getvalue() fmt = '```py\n{}{}\n```'.format(value, traceback.format_exc()) else: self.repl_embeds[shell].color = 4437377 value = stdout.getvalue() if result is not None: fmt = '```py\n{}{}\n```'.format(value, result) variables['_'] = result elif value: fmt = '```py\n{}\n```'.format(value) history[cleaned] = fmt if len(cleaned) > 800: cleaned = "<Too big to be printed>" try: if fmt is not None: if len(fmt) >= 800: haste_url = await self.online.hastebin(fmt) self.repl_embeds[shell].add_field( name="`>>> {}`".format(cleaned), value="[`Content too big to be printed. " "Hosted on hastebin.`]({})".format(haste_url), inline=False) await self.repl_sessions[session].edit( embed=self.repl_embeds[shell]) else: self.repl_embeds[shell].add_field( name="`>>> {}`".format(cleaned), value=fmt, inline=False) await self.repl_sessions[session].edit( embed=self.repl_embeds[shell]) else: self.repl_embeds[shell].add_field( name="`>>> {}`".format(cleaned), value="`Empty response, assumed successful.`", inline=False) await self.repl_sessions[session].edit( embed=self.repl_embeds[shell]) except discord.Forbidden: pass except discord.HTTPException as err: error_embed = discord.Embed( color=15746887, description='**Error**: _{}_'.format(err)) await ctx.send(embed=error_embed)
async def get_formatted_args(self, kwargs): args = self.format_args(**kwargs) if inspect.isawaitable(args): args = await args return args
async def serialize_property(value: 'Input[Any]', deps: List['Resource'], input_transformer: Optional[Callable[[str], str]] = None, typ: Optional[type] = None, keep_output_values: Optional[bool] = None) -> Any: """ Serializes a single Input into a form suitable for remoting to the engine, awaiting any futures required to do so. When `typ` is specified, the metadata from the type is used to translate Python snake_case names to Pulumi camelCase names, rather than using the `input_transformer`. If `keep_output_values` is true and the monitor supports output values, they will be kept. """ # Set typ to T if it's Optional[T], Input[T], or InputType[T]. typ = _types.unwrap_type(typ) if typ else typ # If the typ is Any, set it to None to treat it as if we don't have any type information, # to avoid raising errors about unexpected types, since it could be any type. if typ is Any: typ = None # Exclude some built-in types that are instances of Sequence that we don't want to treat as sequences here. # From: https://github.com/python/cpython/blob/master/Lib/_collections_abc.py if isinstance(value, abc.Sequence) and not isinstance(value, (tuple, str, range, memoryview, bytes, bytearray)): element_type = _get_list_element_type(typ) props = [] for elem in value: props.append(await serialize_property(elem, deps, input_transformer, element_type, keep_output_values)) return props if known_types.is_unknown(value): return UNKNOWN if known_types.is_resource(value): resource = cast('Resource', value) is_custom = known_types.is_custom_resource(value) resource_id = cast('CustomResource', value).id if is_custom else None # If we're retaining resources, serialize the resource as a reference. if await settings.monitor_supports_resource_references(): res = { _special_sig_key: _special_resource_sig, "urn": await serialize_property(resource.urn, deps, input_transformer, keep_output_values=False) } if is_custom: res["id"] = await serialize_property(resource_id, deps, input_transformer, keep_output_values=False) return res # Otherwise, serialize the resource as either its ID (for custom resources) or its URN (for component resources) return await serialize_property(resource_id if is_custom else resource.urn, deps, input_transformer, keep_output_values=False) if known_types.is_asset(value): # Serializing an asset requires the use of a magical signature key, since otherwise it would # look like any old weakly typed object/map when received by the other side of the RPC # boundary. obj = { _special_sig_key: _special_asset_sig } if hasattr(value, "path"): file_asset = cast('FileAsset', value) obj["path"] = await serialize_property(file_asset.path, deps, input_transformer, keep_output_values=False) elif hasattr(value, "text"): str_asset = cast('StringAsset', value) obj["text"] = await serialize_property(str_asset.text, deps, input_transformer, keep_output_values=False) elif hasattr(value, "uri"): remote_asset = cast('RemoteAsset', value) obj["uri"] = await serialize_property(remote_asset.uri, deps, input_transformer, keep_output_values=False) else: raise AssertionError(f"unknown asset type: {value!r}") return obj if known_types.is_archive(value): # Serializing an archive requires the use of a magical signature key, since otherwise it # would look like any old weakly typed object/map when received by the other side of the RPC # boundary. obj = { _special_sig_key: _special_archive_sig } if hasattr(value, "assets"): asset_archive = cast('AssetArchive', value) obj["assets"] = await serialize_property(asset_archive.assets, deps, input_transformer, keep_output_values=False) elif hasattr(value, "path"): file_archive = cast('FileArchive', value) obj["path"] = await serialize_property(file_archive.path, deps, input_transformer, keep_output_values=False) elif hasattr(value, "uri"): remote_archive = cast('RemoteArchive', value) obj["uri"] = await serialize_property(remote_archive.uri, deps, input_transformer, keep_output_values=False) else: raise AssertionError(f"unknown archive type: {value!r}") return obj if inspect.isawaitable(value): # Coroutines and Futures are both awaitable. Coroutines need to be scheduled. # asyncio.ensure_future returns futures verbatim while converting coroutines into # futures by arranging for the execution on the event loop. # # The returned future can then be awaited to yield a value, which we'll continue # serializing. awaitable = cast('Any', value) future_return = await asyncio.ensure_future(awaitable) return await serialize_property(future_return, deps, input_transformer, typ, keep_output_values) if known_types.is_output(value): output = cast('Output', value) value_resources: Set['Resource'] = await output.resources() deps.extend(value_resources) # When serializing an Output, we will either serialize it as its resolved value or the # "unknown value" sentinel. We will do the former for all outputs created directly by user # code (such outputs always resolve isKnown to true) and for any resource outputs that were # resolved with known values. is_known = await output._is_known is_secret = await output._is_secret promise_deps: List['Resource'] = [] value = await serialize_property(output.future(), promise_deps, input_transformer, typ, keep_output_values=False) deps.extend(promise_deps) value_resources.update(promise_deps) if keep_output_values and await settings.monitor_supports_output_values(): urn_deps: List['Resource'] = [] for resource in value_resources: await serialize_property(resource.urn, urn_deps, input_transformer, keep_output_values=False) promise_deps.extend(set(urn_deps)) value_resources.update(urn_deps) dependencies = await _expand_dependencies(value_resources, None) output_value: Dict[str, Any] = { _special_sig_key: _special_output_value_sig } if is_known: output_value["value"] = value if is_secret: output_value["secret"] = is_secret if dependencies: output_value["dependencies"] = sorted(dependencies) return output_value if not is_known: return UNKNOWN if is_secret and await settings.monitor_supports_secrets(): # Serializing an output with a secret value requires the use of a magical signature key, # which the engine detects. return { _special_sig_key: _special_secret_sig, "value": value } return value # If value is an input type, convert it to a dict. value_cls = type(value) if _types.is_input_type(value_cls): value = _types.input_type_to_dict(value) types = _types.input_type_types(value_cls) return { k: await serialize_property(v, deps, input_transformer, types.get(k), keep_output_values) for k, v in value.items() } if isinstance(value, abc.Mapping): # Default implementation of get_type that always returns None. get_type: Callable[[str], Optional[type]] = lambda k: None # Key translator. translate = input_transformer # If we have type information, we'll use it to do name translations rather than using # any passed-in input_transformer. if typ is not None: if _types.is_input_type(typ): # If it's intended to be an input type, translate using the type's metadata. py_name_to_pulumi_name = _types.input_type_py_to_pulumi_names(typ) types = _types.input_type_types(typ) translate = lambda k: py_name_to_pulumi_name.get(k) or k get_type = types.get else: # Otherwise, don't do any translation of user-defined dict keys. origin = _types.get_origin(typ) if typ is dict or origin in {dict, Dict, Mapping, abc.Mapping}: args = _types.get_args(typ) if len(args) == 2 and args[0] is str: get_type = lambda k: args[1] translate = None else: translate = None # Note: Alternatively, we could assert here that we expected a dict type but got some other type, # but there are cases where we've historically allowed a user-defined dict value to be passed even # though the type annotation isn't a dict type (e.g. the `aws.s3.BucketPolicy.policy` input property # is currently typed as `pulumi.Input[str]`, but we've allowed a dict to be passed, which will # "magically" work at runtime because the provider will convert the dict value to a JSON string). # Ideally, we'd update the type annotations for such cases to reflect that a dict could be passed, # but we haven't done that yet and want these existing cases to continue to work as they have # before. obj = {} # Don't use value.items() here, as it will error in the case of outputs with an `items` property. for k in value: transformed_key = k if translate is not None: transformed_key = translate(k) if settings.excessive_debug_output: log.debug(f"transforming input property: {k} -> {transformed_key}") obj[transformed_key] = await serialize_property(value[k], deps, input_transformer, get_type(transformed_key), keep_output_values) return obj # Ensure that we have a value that Protobuf understands. if not isLegalProtobufValue(value): raise ValueError(f"unexpected input of type {type(value).__name__}") return value
async def repl(self, ctx): msg = ctx.message variables = { 'ctx': ctx, 'bot': self.bot, 'message': msg, 'server': msg.server, 'channel': msg.channel, 'author': msg.author, '_': None, } if msg.channel.id in self.sessions: await self.bot.say( 'Already running a REPL session in this channel. Exit it with `quit`.' ) return self.sessions.add(msg.channel.id) await self.bot.say( 'Enter code to execute or evaluate. `exit()` or `quit` to exit.') while True: response = await self.bot.wait_for_message( author=msg.author, channel=msg.channel, check=lambda m: m.content.startswith('`')) cleaned = self.cleanup_code(response.content) if cleaned in ('quit', 'exit', 'exit()'): await self.bot.say('Exiting.') self.sessions.remove(msg.channel.id) return executor = exec if cleaned.count('\n') == 0: # single statement, potentially 'eval' try: code = compile(cleaned, '<repl session>', 'eval') except SyntaxError: pass else: executor = eval if executor is exec: try: code = compile(cleaned, '<repl session>', 'exec') except SyntaxError as e: await self.bot.say(self.get_syntax_error(e)) continue variables['message'] = response fmt = None stdout = io.StringIO() try: with redirect_stdout(stdout): result = executor(code, variables) if inspect.isawaitable(result): result = await result except Exception as e: value = stdout.getvalue() fmt = '```py\n{}{}\n```'.format(value, traceback.format_exc()) else: value = stdout.getvalue() if result is not None: fmt = '```py\n{}{}\n```'.format(value, result) variables['_'] = result elif value: fmt = '```py\n{}\n```'.format(value) try: if fmt is not None: if len(fmt) > 2000: await self.bot.send_message( msg.channel, 'Content too big to be printed.') else: await self.bot.send_message(msg.channel, fmt) except discord.Forbidden: pass except discord.HTTPException as e: await self.bot.send_message(msg.channel, 'Unexpected error: `{}`'.format(e))
async def dispatch_shell(self, msg): """dispatch shell requests""" # flush control queue before handling shell requests await self._flush_control_queue() idents, msg = self.session.feed_identities(msg, copy=False) try: msg = self.session.deserialize(msg, content=True, copy=False) except Exception: self.log.error("Invalid Message", exc_info=True) return # Set the parent message for side effects. self.set_parent(idents, msg, channel='shell') self._publish_status('busy', 'shell') msg_type = msg['header']['msg_type'] # Only abort execute requests if self._aborting and msg_type == 'execute_request': self._send_abort_reply(self.shell_stream, msg, idents) self._publish_status('idle', 'shell') # flush to ensure reply is sent before # handling the next request self.shell_stream.flush(zmq.POLLOUT) return # Print some info about this message and leave a '--->' marker, so it's # easier to trace visually the message chain when debugging. Each # handler prints its message at the end. self.log.debug('\n*** MESSAGE TYPE:%s***', msg_type) self.log.debug(' Content: %s\n --->\n ', msg['content']) if not self.should_handle(self.shell_stream, msg, idents): return handler = self.shell_handlers.get(msg_type, None) if handler is None: self.log.warning("Unknown message type: %r", msg_type) else: self.log.debug("%s: %s", msg_type, msg) try: self.pre_handler_hook() except Exception: self.log.debug("Unable to signal in pre_handler_hook:", exc_info=True) try: result = handler(self.shell_stream, idents, msg) if inspect.isawaitable(result): await result except Exception: self.log.error("Exception in message handler:", exc_info=True) except KeyboardInterrupt: # Ctrl-c shouldn't crash the kernel here. self.log.error("KeyboardInterrupt caught in kernel.") finally: try: self.post_handler_hook() except Exception: self.log.debug("Unable to signal in post_handler_hook:", exc_info=True) sys.stdout.flush() sys.stderr.flush() self._publish_status('idle', 'shell') # flush to ensure reply is sent before # handling the next request self.shell_stream.flush(zmq.POLLOUT)
async def handle_request(self, request, write_callback, stream_callback): """Take a request from the HTTP Server and return a response object to be sent back The HTTP Server only expects a response object, so exception handling must be done here :param request: HTTP Request object :param write_callback: Synchronous response function to be called with the response as the only argument :param stream_callback: Coroutine that handles streaming a StreamingHTTPResponse if produced by the handler. :return: Nothing """ # Define `response` var here to remove warnings about # allocation before assignment below. response = None cancelled = False try: # -------------------------------------------- # # Request Middleware # -------------------------------------------- # request.app = self response = await self._run_request_middleware(request) # No middleware results if not response: # -------------------------------------------- # # Execute Handler # -------------------------------------------- # # Fetch handler from router handler, args, kwargs, uri = self.router.get(request) request.uri_template = uri if handler is None: raise ServerError( ("'None' was returned while requesting a " "handler from the router")) # Run response handler response = handler(request, *args, **kwargs) if isawaitable(response): response = await response except CancelledError: # If response handler times out, the server handles the error # and cancels the handle_request job. # In this case, the transport is already closed and we cannot # issue a response. response = None cancelled = True except Exception as e: # -------------------------------------------- # # Response Generation Failed # -------------------------------------------- # try: response = self.error_handler.response(request, e) if isawaitable(response): response = await response except Exception as e: if isinstance(e, SanicException): response = self.error_handler.default(request=request, exception=e) elif self.debug: response = HTTPResponse( "Error while handling error: {}\nStack: {}".format( e, format_exc()), status=500) else: response = HTTPResponse( "An error occurred while handling an error", status=500) finally: # -------------------------------------------- # # Response Middleware # -------------------------------------------- # # Don't run response middleware if response is None if response is not None: try: response = await self._run_response_middleware(request, response) except CancelledError: # Response middleware can timeout too, as above. response = None cancelled = True except BaseException: error_logger.exception( 'Exception occurred in one of response ' 'middleware handlers' ) if cancelled: raise CancelledError() # pass the response to the correct callback if isinstance(response, StreamingHTTPResponse): await stream_callback(response) else: write_callback(response)
async def recognizes_a_coroutine_object(): async def some_coroutine(): return False # pragma: no cover assert isawaitable(some_coroutine()) assert is_awaitable(some_coroutine())
def declines_a_string_value(): assert not isawaitable("some_string") assert not is_awaitable("some_string")
def declines_the_none_value(): assert not isawaitable(None) assert not is_awaitable(None)
def declines_an_async_generator(): async def some_async_generator(): yield True # pragma: no cover assert not isawaitable(some_async_generator()) assert not is_awaitable(some_async_generator())
def declines_the_type_class(): assert not isawaitable(type) assert not is_awaitable(type)
async def graphql( schema: GraphQLSchema, data: Any, *, context_value: Optional[Any] = None, root_value: Optional[RootValue] = None, debug: bool = False, introspection: bool = True, logger: Optional[str] = None, validation_rules: Optional[ValidationRules] = None, error_formatter: ErrorFormatter = format_error, middleware: Optional[MiddlewareManager] = None, extensions: Optional[List[Type[Extension]]] = None, **kwargs, ) -> GraphQLResult: extension_manager = ExtensionManager(extensions, context_value) with extension_manager.request(): try: validate_data(data) query, variables, operation_name = ( data["query"], data.get("variables"), data.get("operationName"), ) document = parse_query(query) if callable(validation_rules): validation_rules = cast( Optional[Sequence[RuleType]], validation_rules(context_value, document, data), ) validation_errors = validate_query( schema, document, validation_rules, enable_introspection=introspection) if validation_errors: return handle_graphql_errors( validation_errors, logger=logger, error_formatter=error_formatter, debug=debug, extension_manager=extension_manager, ) if callable(root_value): root_value = root_value(context_value, document) if isawaitable(root_value): root_value = await root_value result = execute( schema, document, root_value=root_value, context_value=context_value, variable_values=variables, operation_name=operation_name, execution_context_class=ExecutionContext, middleware=extension_manager.as_middleware_manager(middleware), **kwargs, ) if isawaitable(result): result = await cast(Awaitable[ExecutionResult], result) except GraphQLError as error: return handle_graphql_errors( [error], logger=logger, error_formatter=error_formatter, debug=debug, extension_manager=extension_manager, ) else: return handle_query_result( result, logger=logger, error_formatter=error_formatter, debug=debug, extension_manager=extension_manager, )