aboutsummaryrefslogtreecommitdiffstats
path: root/python/gevent/_util.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/gevent/_util.py')
-rw-r--r--python/gevent/_util.py90
1 files changed, 81 insertions, 9 deletions
diff --git a/python/gevent/_util.py b/python/gevent/_util.py
index 4178a84..4397aa3 100644
--- a/python/gevent/_util.py
+++ b/python/gevent/_util.py
@@ -5,6 +5,8 @@ internal gevent utilities, not for external use.
from __future__ import print_function, absolute_import, division
+from functools import update_wrapper
+
from gevent._compat import iteritems
@@ -29,21 +31,22 @@ def copy_globals(source,
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 globals()).
+ 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
+ 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 AttributeError
- if one of those names can't be found.
+ 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.
+ 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
+ Returns a list of the names copied; this should be assigned to ``__imports__``.
"""
if only_names:
if ignore_missing_names:
@@ -70,6 +73,47 @@ def copy_globals(source,
return copied
+def import_c_accel(globs, cname):
+ """
+ Import the C-accelerator for the __name__
+ and copy its globals.
+ """
+
+ name = globs.get('__name__')
+
+ if not name or name == cname:
+ # Do nothing if we're being exec'd as a file (no name)
+ # or we're running from the C extension
+ return
+
+
+ from gevent._compat import PURE_PYTHON
+ if PURE_PYTHON:
+ return
+
+ import importlib
+ import warnings
+ with warnings.catch_warnings():
+ # Python 3.7 likes to produce
+ # "ImportWarning: can't resolve
+ # package from __spec__ or __package__, falling back on
+ # __name__ and __path__"
+ # when we load cython compiled files. This is probably a bug in
+ # Cython, but it doesn't seem to have any consequences, it's
+ # just annoying to see and can mess up our unittests.
+ warnings.simplefilter('ignore', ImportWarning)
+ mod = importlib.import_module(cname)
+
+ # By adopting the entire __dict__, we get a more accurate
+ # __file__ and module repr, plus we don't leak any imported
+ # things we no longer need.
+ globs.clear()
+ globs.update(mod.__dict__)
+
+ if 'import_c_accel' in globs:
+ del globs['import_c_accel']
+
+
class Lazy(object):
"""
A non-data descriptor used just like @property. The
@@ -79,6 +123,7 @@ class Lazy(object):
"""
def __init__(self, func):
self.data = (func, func.__name__)
+ update_wrapper(self, func)
def __get__(self, inst, class_):
if inst is None:
@@ -98,9 +143,36 @@ class readproperty(object):
def __init__(self, func):
self.func = func
+ update_wrapper(self, func)
def __get__(self, inst, class_):
if inst is None:
return self
return self.func(inst)
+
+def gmctime():
+ """
+ Returns the current time as a string in RFC3339 format.
+ """
+ import time
+ return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
+
+try:
+ from zope.interface import Interface
+ from zope.interface import implementer
+ from zope.interface import Attribute
+except ImportError:
+ class Interface(object):
+ pass
+ def implementer(_iface):
+ def dec(c):
+ return c
+ return dec
+
+ def Attribute(s):
+ return s
+
+Interface = Interface
+implementer = implementer
+Attribute = Attribute