def poll(self, timeout=None): """ poll the registered fds. .. versionchanged:: 1.2a1 File descriptors that are closed are reported with POLLNVAL. """ result = PollResult() watchers = [] io = self.loop.io MAXPRI = self.loop.MAXPRI try: for fd, flags in iteritems(self.fds): watcher = io(fd, flags) watchers.append(watcher) watcher.priority = MAXPRI watcher.start(result.add_event, fd, pass_events=True) if timeout is not None and timeout > -1: timeout /= 1000.0 result.event.wait(timeout=timeout) return list(result.events) finally: for awatcher in watchers: awatcher.stop() awatcher.close()
def __init__(self, importing): self._saved = {} self.importing = importing self.green_modules = { stdlib_name: importlib.import_module(gevent_name) for gevent_name, stdlib_name in iteritems(MAPPING) } self.orig_imported = frozenset(sys.modules)
def _restore(self): # Anything from the same package tree we imported this time # needs to be saved so we can restore it later, and so it doesn't # leak into the namespace. for modname, mod in list(iteritems(sys.modules)): if modname.startswith(self.importing): self._green_modules[modname] = mod del sys.modules[modname] # Now, what we saved at the beginning needs to be restored. for modname, mod in iteritems(self._t_modules_to_restore): if mod is not None: sys.modules[modname] = mod else: try: del sys.modules[modname] except KeyError: pass
def _restore(self): for modname, mod in iteritems(self._saved): if mod is not None: sys.modules[modname] = mod else: try: del sys.modules[modname] except KeyError: pass # Anything from the same package tree we imported this time # needs to be saved so we can restore it later, and so it doesn't # leak into the namespace. pkg_prefix = self.importing.split('.', 1)[0] for modname, mod in list(iteritems(sys.modules)): if (modname not in self.orig_imported and modname != self.importing and not modname.startswith(_PATCH_PREFIX) and modname.startswith(pkg_prefix)): sys.modules[_PATCH_PREFIX + modname] = mod del sys.modules[modname]
def _save(self): self._t_modules_to_restore = {} # Copy all the things we know we are going to overwrite. for modname in self._green_modules: self._t_modules_to_restore[modname] = sys.modules.get(modname, None) # Copy anything else in the import tree. for modname, mod in list(iteritems(sys.modules)): if modname.startswith(self.importing): self._t_modules_to_restore[modname] = mod # And remove it. If it had been imported green, it will # be put right back. Otherwise, it was imported "manually" # outside this process and isn't green. del sys.modules[modname] # Cover the target modules so that when you import the module it # sees only the patched versions for name, mod in iteritems(self._green_modules): sys.modules[name] = mod
def _save(self): for modname in self.green_modules: self._saved[modname] = sys.modules.get(modname, None) self._saved[self.importing] = sys.modules.get(self.importing, None) # Anything we've already patched regains its original name during this # process for mod_name, mod in iteritems(sys.modules): if mod_name.startswith(_PATCH_PREFIX): orig_mod_name = mod_name[len(_PATCH_PREFIX):] self._saved[mod_name] = sys.modules.get(orig_mod_name, None) self.green_modules[orig_mod_name] = mod
def copy_globals(source, globs, only_names=None, ignore_missing_names=False, names_to_ignore=(), dunder_names_to_keep=('__implements__', '__all__', '__imports__'), cleanup_globs=True): """ Copy attributes defined in ``source.__dict__`` to the dictionary in globs (which should be the caller's :func:`globals`). Names that start with ``__`` are ignored (unless they are in *dunder_names_to_keep*). Anything found in *names_to_ignore* is also ignored. If *only_names* is given, only those attributes will be considered. In this case, *ignore_missing_names* says whether or not to raise an :exc:`AttributeError` if one of those names can't be found. If *cleanup_globs* has a true value, then common things imported but not used at runtime are removed, including this function. Returns a list of the names copied; this should be assigned to ``__imports__``. """ if only_names: if ignore_missing_names: items = ((k, getattr(source, k, _NONE)) for k in only_names) else: items = ((k, getattr(source, k)) for k in only_names) else: items = iteritems(source.__dict__) copied = [] for key, value in items: if value is _NONE: continue if key in names_to_ignore: continue if key.startswith("__") and key not in dunder_names_to_keep: continue globs[key] = value copied.append(key) if cleanup_globs: if 'copy_globals' in globs: del globs['copy_globals'] return copied
def __init__(self, importing, extra_all=lambda mod_name: ()): # Permanent state. self.extra_all = extra_all self.importing = importing # green modules, replacing regularly imported modules. # This begins as the gevent list of modules, and # then gets extended with green things from the tree we import. self._green_modules = { stdlib_name: importlib.import_module(gevent_name) for gevent_name, stdlib_name in iteritems(MAPPING) } ## Transient, reset each time we're called. # The set of things imported before we began. self._t_modules_to_restore = {}
def poll(self, timeout=None): """ poll the registered fds. .. versionchanged:: 1.2a1 File descriptors that are closed are reported with POLLNVAL. .. versionchanged:: 1.3a2 Under libuv, interpret *timeout* values less than 0 the same as *None*, i.e., block. This was always the case with libev. """ result = PollResult() watchers = [] io = self.loop.io MAXPRI = self.loop.MAXPRI try: for fd, flags in iteritems(self.fds): watcher = io(fd, flags) watchers.append(watcher) watcher.priority = MAXPRI watcher.start(result.add_event, fd, pass_events=True) if timeout is not None: if timeout < 0: # The docs for python say that an omitted timeout, # a negative timeout and a timeout of None are all # supposed to block forever. Many, but not all # OS's accept any negative number to mean that. Some # OS's raise errors for anything negative but not -1. # Python 3.7 changes to always pass exactly -1 in that # case from selectors. # Our Timeout class currently does not have a defined behaviour # for negative values. On libuv, it uses a check watcher and effectively # doesn't block. On libev, it seems to block. In either case, we # *want* to block, so turn this into the sure fire block request. timeout = None elif timeout: # The docs for poll.poll say timeout is in # milliseconds. Our result objects work in # seconds, so this should be *=, shouldn't it? timeout /= 1000.0 result.event.wait(timeout=timeout) return list(result.events) finally: for awatcher in watchers: awatcher.stop() awatcher.close()
def _get_started_watchers(self, watcher_cb): watchers = [] io = self.loop.io MAXPRI = self.loop.MAXPRI try: for fd, flags in iteritems(self.fds): watcher = io(fd, flags) watchers.append(watcher) watcher.priority = MAXPRI watcher.start(watcher_cb, fd, pass_events=True) except: for awatcher in watchers: awatcher.stop() awatcher.close() raise return watchers
def _collect_stdlib_gevent_modules(): """ Return a map from standard library name to imported gevent module that provides the same API. Optional modules are skipped if they cannot be imported. """ result = {} for gevent_name, stdlib_name in iteritems(MAPPING): try: result[stdlib_name] = importlib.import_module(gevent_name) except ImportError: if stdlib_name in OPTIONAL_STDLIB_MODULES: continue raise return result
def getaliases(self, hostname): # Return a list of all the aliases of a given cname # Due to the way store aliases this is a bit inefficient, this # clearly was an afterthought. But this is only used by # gethostbyname_ex so it's probably fine. aliases = self.hosts_file.aliases result = [] if hostname in aliases: cannon = aliases[hostname] else: cannon = hostname result.append(cannon) for alias, cname in iteritems(aliases): if cannon == cname: result.append(alias) result.remove(hostname) return result
def poll(self, timeout=None): """ poll the registered fds. .. versionchanged:: 1.2a1 File descriptors that are closed are reported with POLLNVAL. """ result = PollResult() try: for fd, watcher in iteritems(self.fds): watcher.start(result.add_event, fd, pass_events=True) if timeout is not None and timeout > -1: timeout /= 1000.0 result.event.wait(timeout=timeout) return list(result.events) finally: for awatcher in itervalues(self.fds): awatcher.stop()
def iter_all_host_addr_pairs(self): self.load() for name, addr in iteritems(self.v4): yield name, addr for name, addr in iteritems(self.v6): yield name, addr
def select(self, timeout=None): """ Poll for I/O. Note that, like the built-in selectors, this will block indefinitely if no timeout is given and no files have been registered. """ # timeout > 0 : block seconds # timeout <= 0 : No blocking. # timeout = None: Block forever # Event.wait doesn't deal with negative values if timeout is not None and timeout < 0: timeout = 0 # Start any watchers that need started. Note that they may # not actually get a chance to do anything yet if we already had # events set. for fd, watcher in iteritems(self._inactive_watchers): watcher.start(self.__callback, fd, pass_events=True) self._active_watchers.update(self._inactive_watchers) self._inactive_watchers.clear() # The _ready event is either already set (in which case # there are some results waiting in _accumulated_events) or # not set, in which case we have to block. But to make the two cases # behave the same, we will always yield to the event loop. if self._ready.is_set(): sleep() self._ready.wait(timeout) self._ready.clear() # TODO: If we have nothing ready, but they ask us not to block, # should we make an effort to actually spin the event loop and let # it check for events? result = [] for fd, event in iteritems(self._accumulated_events): key = self._key_from_fd(fd) watcher = self._active_watchers.pop(fd) ## The below is taken without comment from ## https://github.com/gevent/gevent/pull/1523/files and ## hasn't been checked: # # Since we are emulating an epoll object within another epoll object, # once a watcher has fired, we must deactivate it until poll is called # next. If we did not, someone else could call, e.g., gevent.time.sleep # and any unconsumed bytes on our watched fd would prevent the process # from sleeping correctly. watcher.stop() if key: result.append((key, event & key.events)) self._inactive_watchers[fd] = watcher else: # pragma: no cover # If the key was gone, then somehow we've been unregistered. # Don't put it back in inactive, close it. watcher.close() self._accumulated_events.clear() return result
def _replace(self): # Cover the target modules so that when you import the module it # sees only the patched versions for name, mod in iteritems(self.green_modules): sys.modules[name] = mod