track embedded python distribution
This commit is contained in:
106
python/gevent/_util.py
Normal file
106
python/gevent/_util.py
Normal file
@@ -0,0 +1,106 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
internal gevent utilities, not for external use.
|
||||
"""
|
||||
|
||||
from __future__ import print_function, absolute_import, division
|
||||
|
||||
from gevent._compat import iteritems
|
||||
|
||||
|
||||
class _NONE(object):
|
||||
"""
|
||||
A special object you must never pass to any gevent API.
|
||||
Used as a marker object for keyword arguments that cannot have the
|
||||
builtin None (because that might be a valid value).
|
||||
"""
|
||||
__slots__ = ()
|
||||
|
||||
def __repr__(self):
|
||||
return '<default value>'
|
||||
|
||||
_NONE = _NONE()
|
||||
|
||||
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 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 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
|
||||
"""
|
||||
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
|
||||
|
||||
class Lazy(object):
|
||||
"""
|
||||
A non-data descriptor used just like @property. The
|
||||
difference is the function value is assigned to the instance
|
||||
dict the first time it is accessed and then the function is never
|
||||
called agoin.
|
||||
"""
|
||||
def __init__(self, func):
|
||||
self.data = (func, func.__name__)
|
||||
|
||||
def __get__(self, inst, class_):
|
||||
if inst is None:
|
||||
return self
|
||||
|
||||
func, name = self.data
|
||||
value = func(inst)
|
||||
inst.__dict__[name] = value
|
||||
return value
|
||||
|
||||
class readproperty(object):
|
||||
"""
|
||||
A non-data descriptor like @property. The difference is that
|
||||
when the property is assigned to, it is cached in the instance
|
||||
and the function is not called on that instance again.
|
||||
"""
|
||||
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __get__(self, inst, class_):
|
||||
if inst is None:
|
||||
return self
|
||||
|
||||
return self.func(inst)
|
||||
Reference in New Issue
Block a user