def set_exposed_property_value(obj, propname, value, only_exposed=True):
"""
Sets the value of an @exposed @property.
If the requested property is not a @property or not exposed,
an AttributeError is raised instead.
"""
v = getattr(obj.__class__, propname)
if inspect.isdatadescriptor(v):
pfunc = v.fget or v.fset or v.fdel
if v.fset and getattr(pfunc, "_pyroExposed", not only_exposed):
return v.fset(obj, value)
raise AttributeError("attempt to access unexposed or unknown remote attribute '%s'" % propname)
python类isdatadescriptor()的实例源码
def test_excluding_predicates(self):
global tb
self.istest(inspect.isbuiltin, 'sys.exit')
self.istest(inspect.isbuiltin, '[].append')
self.istest(inspect.iscode, 'mod.spam.__code__')
try:
1/0
except:
tb = sys.exc_info()[2]
self.istest(inspect.isframe, 'tb.tb_frame')
self.istest(inspect.istraceback, 'tb')
if hasattr(types, 'GetSetDescriptorType'):
self.istest(inspect.isgetsetdescriptor,
'type(tb.tb_frame).f_locals')
else:
self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
finally:
# Clear traceback and all the frames and local variables hanging to it.
tb = None
self.istest(inspect.isfunction, 'mod.spam')
self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
self.istest(inspect.ismethod, 'git.argue')
self.istest(inspect.ismodule, 'mod')
self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
self.istest(inspect.isgenerator, '(x for x in range(2))')
self.istest(inspect.isgeneratorfunction, 'generator_function_example')
if hasattr(types, 'MemberDescriptorType'):
self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
else:
self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
def test_getmembers_descriptors(self):
class A(object):
dd = _BrokenDataDescriptor()
md = _BrokenMethodDescriptor()
def pred_wrapper(pred):
# A quick'n'dirty way to discard standard attributes of new-style
# classes.
class Empty(object):
pass
def wrapped(x):
if '__name__' in dir(x) and hasattr(Empty, x.__name__):
return False
return pred(x)
return wrapped
ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
[('md', A.__dict__['md'])])
self.assertEqual(inspect.getmembers(A, isdatadescriptor),
[('dd', A.__dict__['dd'])])
class B(A):
pass
self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
[('md', A.__dict__['md'])])
self.assertEqual(inspect.getmembers(B, isdatadescriptor),
[('dd', A.__dict__['dd'])])
def classify_class_attrs(object):
"""Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
results = []
for (name, kind, cls, value) in inspect.classify_class_attrs(object):
if inspect.isdatadescriptor(value):
kind = 'data descriptor'
results.append((name, kind, cls, value))
return results
# ----------------------------------------------------- module manipulation
def classify_class_attrs(object):
"""Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
def fixup(data):
name, kind, cls, value = data
if inspect.isdatadescriptor(value):
kind = 'data descriptor'
return name, kind, cls, value
return map(fixup, inspect.classify_class_attrs(object))
# ----------------------------------------------------- Unicode support helpers
test_docstring_parameters.py 文件源码
项目:decoding_challenge_cortana_2016_3rd
作者: kingjr
项目源码
文件源码
阅读 21
收藏 0
点赞 0
评论 0
def check_parameters_match(func, doc=None):
"""Helper to check docstring, returns list of incorrect results"""
incorrect = []
name_ = get_name(func)
if not name_.startswith('mne.') or name_.startswith('mne.externals'):
return incorrect
if inspect.isdatadescriptor(func):
return incorrect
args = _get_args(func)
# drop self
if len(args) > 0 and args[0] == 'self':
args = args[1:]
if doc is None:
with warnings.catch_warnings(record=True) as w:
doc = docscrape.FunctionDoc(func)
if len(w):
raise RuntimeError('Error for %s:\n%s' % (name_, w[0]))
# check set
param_names = [name for name, _, _ in doc['Parameters']]
# clean up some docscrape output:
param_names = [name.split(':')[0].strip('` ') for name in param_names]
param_names = [name for name in param_names if '*' not in name]
if len(param_names) != len(args):
bad = str(sorted(list(set(param_names) - set(args)) +
list(set(args) - set(param_names))))
if not any(d in name_ for d in _docstring_ignores) and \
'deprecation_wrapped' not in func.__code__.co_name:
incorrect += [name_ + ' arg mismatch: ' + bad]
else:
for n1, n2 in zip(param_names, args):
if n1 != n2:
incorrect += [name_ + ' ' + n1 + ' != ' + n2]
return incorrect
def inspectproperties(klass):
"""Inspects the properties of a class (does not work for an instance)."""
for name, value in inspect.getmembers(klass, predicate=inspect.isdatadescriptor):
print name, value
print "\tDoc:", inspect.getdoc(value)
def get_props_of(cls):
if cls not in cls._props_by_class:
cls._props_by_class[cls] = dict(pyinspect.getmembers(
cls, lambda p: pyinspect.isdatadescriptor(p)))
return cls._props_by_class[cls]
def expose(method_or_class):
"""
Decorator to mark a method or class to be exposed for remote calls.
You can apply it to a method or a class as a whole.
If you need to change the default instance mode or instance creator, also use a @behavior decorator.
"""
if inspect.isdatadescriptor(method_or_class):
func = method_or_class.fget or method_or_class.fset or method_or_class.fdel
if is_private_attribute(func.__name__):
raise AttributeError("exposing private names (starting with _) is not allowed")
func._pyroExposed = True
return method_or_class
attrname = getattr(method_or_class, "__name__", None)
if not attrname:
# we could be dealing with a descriptor (classmethod/staticmethod), this means the order of the decorators is wrong
if inspect.ismethoddescriptor(method_or_class):
attrname = method_or_class.__get__(None, dict).__name__
raise AttributeError("using @expose on a classmethod/staticmethod must be done "
"after @classmethod/@taticmethod. Method: " + attrname)
else:
raise AttributeError("@expose cannot determine what this is: "+repr(method_or_class))
if is_private_attribute(attrname):
raise AttributeError("exposing private names (starting with _) is not allowed")
if inspect.isclass(method_or_class):
clazz = method_or_class
log.debug("exposing all members of %r", clazz)
for name in clazz.__dict__:
if is_private_attribute(name):
continue
thing = getattr(clazz, name)
if inspect.isfunction(thing):
thing._pyroExposed = True
elif inspect.ismethod(thing):
thing.__func__._pyroExposed = True
elif inspect.isdatadescriptor(thing):
if getattr(thing, "fset", None):
thing.fset._pyroExposed = True
if getattr(thing, "fget", None):
thing.fget._pyroExposed = True
if getattr(thing, "fdel", None):
thing.fdel._pyroExposed = True
clazz._pyroExposed = True
return clazz
method_or_class._pyroExposed = True
return method_or_class
def get_exposed_members(obj, only_exposed=True, as_lists=False, use_cache=True):
"""
Return public and exposed members of the given object's class.
You can also provide a class directly.
Private members are ignored no matter what (names starting with underscore).
If only_exposed is True, only members tagged with the @expose decorator are
returned. If it is False, all public members are returned.
The return value consists of the exposed methods, exposed attributes, and methods
tagged as @oneway.
(All this is used as meta data that Pyro sends to the proxy if it asks for it)
as_lists is meant for python 2 compatibility.
"""
if not inspect.isclass(obj):
obj = obj.__class__
cache_key = (obj, only_exposed, as_lists)
if use_cache and cache_key in __exposed_member_cache:
return __exposed_member_cache[cache_key]
methods = set() # all methods
oneway = set() # oneway methods
attrs = set() # attributes
for m in dir(obj): # also lists names inherited from super classes
if is_private_attribute(m):
continue
v = getattr(obj, m)
if inspect.ismethod(v) or inspect.isfunction(v):
if getattr(v, "_pyroExposed", not only_exposed):
methods.add(m)
# check if the method is marked with the 'oneway' decorator:
if getattr(v, "_pyroOneway", False):
oneway.add(m)
elif inspect.isdatadescriptor(v):
func = getattr(v, "fget", None) or getattr(v, "fset", None) or getattr(v, "fdel", None)
if func is not None and getattr(func, "_pyroExposed", not only_exposed):
attrs.add(m)
# Note that we don't expose plain class attributes no matter what.
# it is a syntax error to add a decorator on them, and it is not possible
# to give them a _pyroExposed tag either.
# The way to expose attributes is by using properties for them.
# This automatically solves the protection/security issue: you have to
# explicitly decide to make an attribute into a @property (and to @expose it)
# before it becomes remotely accessible.
if as_lists:
methods = list(methods)
oneway = list(oneway)
attrs = list(attrs)
result = {
"methods": methods,
"oneway": oneway,
"attrs": attrs
}
__exposed_member_cache[cache_key] = result
return result
def update_from_form(instance, form_data=None):
mapper = inspect(instance.__class__)
cols = {c.key: c for c in mapper.columns if not c.foreign_keys}
setables = dict(pyinspect.getmembers(
instance.__class__, lambda p:
pyinspect.isdatadescriptor(p) and getattr(p, 'fset', None)))
relns = {r.key: r for r in mapper.relationships if not r.uselist and
len(r._calculated_foreign_keys) == 1 and iter(
r._calculated_foreign_keys).next().table == mapper.local_table
}
unknown = set(form_data.keys()) - (
set(cols.keys()).union(set(setables.keys())).union(set(relns.keys())))
if unknown:
raise HTTPBadRequest("Unknown keys: "+",".join(unknown))
params = dict(form_data)
# type checking
columns = {c.key: c for c in mapper.columns}
for key, value in params.items():
if key in relns and isinstance(value, string_types):
val_inst = relns[key].class_.get_instance(value)
if not val_inst:
raise HTTPBadRequest("Unknown instance: "+value)
params[key] = val_inst
elif key in columns and isinstance(columns[key].type, DeclEnumType) \
and isinstance(value, string_types):
val_det = columns[key].type.enum.from_string(value)
if not val_det:
raise HTTPBadRequest("Cannot interpret " + value)
params[key] = val_det
elif key in columns and columns[key].type.python_type == datetime.datetime \
and isinstance(value, string_types):
val_dt = datetime.datetime.strpstr(value)
if not val_dt:
raise HTTPBadRequest("Cannot interpret " + value)
params[key] = val_dt
elif key in columns and columns[key].type.python_type == int \
and isinstance(value, string_types):
try:
params[key] = int(value)
except ValueError:
raise HTTPBadRequest("Not a number: " + value)
elif key in columns and not isinstance(value, columns[key].type.python_type):
raise HTTPBadRequest("Value %s for key %s should be a %s" % (
value, key, columns[key].type.python_type))
try:
for key, value in params.items():
setattr(instance, key, value)
except:
raise HTTPBadRequest()