def test_ipy3_gh230(self): """https://github.com/IronLanguages/ironpython3/pull/230""" import inspect class test(object): pass self.assertFalse(inspect.ismethoddescriptor(test.__weakref__)) self.assertFalse(inspect.ismethoddescriptor(test.__dict__["__dict__"]))
def func(self): import inspect print 'f**k' print inspect.ismethoddescriptor(self.__class__.x) for a in dir(self): v = getattr(self, a) print '{0} -- {1} -- {2}'.format(str(a), str(v), type(a)) print type(self.x) print type(self.y)
def cfunc(cls): import inspect #for name, value in ((name, getattr(cls, name, None)) for name in dir(cls) if not name.startswith('_')): # print '' print inspect.ismethoddescriptor(cls.x) for a in dir(cls): v = getattr(cls, a) print '{0} -- {1} -- {2}'.format(str(a), str(v), type(v))
def _hook_variable(self): """Responsible for hooking Variable methods""" # Overload 'special' methods here self._hook___new__(torch.autograd.variable.Variable) self._hook_var_contents() self._hook_var_owners() for attr in dir(torch.autograd.variable.Variable): # Conditions for inclusion/exclusion if attr in self.exclude + self.var_exclude: continue lit = getattr(torch.autograd.variable.Variable, attr) is_base = attr in dir(object) is_desc = inspect.ismethoddescriptor(lit) # is_func = isinstance(type(lit), types.FunctionType) is_func = isinstance(lit, types.FunctionType) try: is_service_func = 'HookService' in lit.__qualname__ except: is_service_func = False is_old = re.match('old*', attr) is not None # Where the overloading happens if ((is_desc or (is_func and not is_service_func)) and not is_base and not is_old): passer = utils.pass_method_args(lit) new_attr = self._get_overload_method_in_tensor_or_var(passer) setattr(torch.autograd.variable.Variable, 'old_{}'.format(attr), lit) setattr(torch.autograd.variable.Variable, attr, new_attr) self._hook_send_(torch.autograd.variable.Variable) self._hook_get_(torch.autograd.variable.Variable) self._hook_var_serde()
def PrintHtml(name, things): """Print HTML documentation to stdout.""" ambiguous = len(things) > 1 content = "" for thing in things: obj, name = pydoc.resolve(thing, forceload=0) title = pydoc.describe(obj) if ambiguous: if inspect.ismethoddescriptor(obj): content += '\n\n<h2>method %s in class %s</h2>\n' % (obj.__name__, obj.__dict__) else: content += '<h2>%s in module <a href="py:%s">%s</a></h2>\n' % (title, obj.__module__, obj.__module__) content += pydoc.html.document(obj, name) if ambiguous: title = 'Matches for "%s"' % name content = '<h1>%s</h1>\n\n%s' % (title, content) page = pydoc.html.page(title, content) # Note: rewriting the anchors in a form more useful to Evergreen should be in Evergreen, not here. # The rewriting here should be generally useful to anyone or anything that needs Python documentation. # Remove a couple of useless (and seemingly broken) links. page = page.replace('<a href=".">index</a><br>', '') page = re.sub('<br><a href="[^"]+\.html">Module Docs</a>', '', page) # There's a bug in pydoc that makes it output the text of the "Modules" section in cyan instead of white. page = re.sub('"#fffff"', '"#ffffff"', page) # The explicit font specifications are unnecessary manual uglification. page = re.sub(' face="[^"]+"', '', page); sys.stdout.write(page + '\n')
def getAttributes(self): # remove the security proxy, so that `attr` is not proxied. We could # unproxy `attr` for each turn, but that would be less efficient. # # `getPermissionIds()` also expects the class's security checker not # to be proxied. klass = zope.security.proxy.removeSecurityProxy(self.klassView.context) obj = zope.security.proxy.removeSecurityProxy(self.context) for name in apidoc.utilities.getPublicAttributes(obj): value = getattr(obj, name) if inspect.ismethod(value) or inspect.ismethoddescriptor(value): # Because getPublicAttributes(obj) loops through # dir(obj) which is more or less obj.__dict__, and # when obj is an instance (and not a class), its # __dict__ tends not to have methods in it, so this condition # should typically not be taken. continue # pragma: no cover entry = { 'name': name, 'value': repr(value), 'value_linkable': IPhysicallyLocatable(value, False) and True, 'type': type(value).__name__, 'type_link': getTypeLink(type(value)), 'interface': apidoc.utilities.getInterfaceForAttribute( name, klass._Class__all_ifaces) } entry.update(apidoc.utilities.getPermissionIds( name, klass.getSecurityChecker())) yield entry
def return_feasible_playback_modes(syspath): l = [] try: import vlc if USE_VLC_RAW_INTERFACE: # check if the special raw interface is available # pylint: disable-msg=E1101 if not inspect.ismethoddescriptor(vlc.MediaControl.set_raw_callbacks): raise Exception("Incorrect vlc plugin. This does not provide the set_raw_callbacks method") # pylint: enable-msg=E1101 vlcpath = os.path.join(syspath,"vlc") if sys.platform == 'win32': if os.path.isdir(vlcpath): l.append(PLAYBACKMODE_INTERNAL) else: l.append(PLAYBACKMODE_INTERNAL) except Exception: print_exc() if sys.platform == 'win32': l.append(PLAYBACKMODE_EXTERNAL_MIME) l.append(PLAYBACKMODE_EXTERNAL_DEFAULT) else: l.append(PLAYBACKMODE_EXTERNAL_DEFAULT) return l
def run(self, args): proc = self.proc arg = proc.cmd_argstr try: if not proc.curframe: # ?? Should we have set up a dummy globals # to have persistence? value = eval(arg, None, None) else: value = eval(arg, proc.curframe.f_globals, proc.curframe.f_locals) except: t, v = sys.exc_info()[:2] if type(t) == str: exc_type_name = t else: exc_type_name = t.__name__ if exc_type_name == 'NameError': self.errmsg("Name Error: %s" % arg) else: self.errmsg("%s: %s" % (exc_type_name, proc._saferepr(v))) return False self.section("What is for %s" % arg) get_doc = False if inspect.ismethod(value): get_doc = True self.msg('method %s%s' % (value.func_code.co_name, inspect.formatargspec(inspect.getargspec(value)))) elif inspect.isfunction(value): get_doc = True self.msg('function %s%s' % (value.func_code.co_name, inspect.formatargspec(inspect.getargspec(value)))) elif inspect.isabstract(value) or \ inspect.isbuiltin(value) or \ inspect.isclass(value) or \ inspect.isgeneratorfunction(value) or \ inspect.ismethoddescriptor(value): get_doc = True self.msg(type(value)) doc = inspect.getdoc(value) if get_doc and doc: self.msg(' doc:\n%s' % doc) comments = inspect.getcomments(value) if comments: self.msg(' comments:\n%s' % comments) try: m = inspect.getmodule(value) if m: self.msg(" module:\t%s" % m) except: try: f = inspect.getfile(value) self.msg(" file: %s" % f) except: pass pass return False
def return_feasible_playback_modes(syspath): l = [] try: if sys.platform == "darwin": oldpath = os.getcwd() os.chdir(os.path.join(syspath,'vlc','lib')) import vlc.lib.vlc as vlc os.chdir(oldpath) else: import Tribler.vlc as vlc if USE_VLC_RAW_INTERFACE: # check if the special raw interface is available # pylint: disable-msg=E1101 if not inspect.ismethoddescriptor(vlc.MediaControl.set_raw_callbacks): raise Exception("Incorrect vlc plugin. This does not provide the set_raw_callbacks method") # pylint: enable-msg=E1101 l.append(PLAYBACKMODE_INTERNAL) # boudewijn: 06/06/2011: if import vlc was ok, then we can also find the vlc dll/so # vlcpath = os.path.join(syspath,"vlc") # if sys.platform == 'win32': # # if os.path.isdir(vlcpath): # l.append(PLAYBACKMODE_INTERNAL) # else: # l.append(PLAYBACKMODE_INTERNAL) except Exception: print_exc() if sys.platform == 'win32': l.append(PLAYBACKMODE_EXTERNAL_MIME) l.append(PLAYBACKMODE_EXTERNAL_DEFAULT) else: l.append(PLAYBACKMODE_EXTERNAL_DEFAULT) return l
def should_be_checked( self, obj, module=None ): """returns True, if obj should be checked, False otherwise""" if id(obj) in self.__checked: return False if inspect.isbuiltin( obj ): return False if inspect.ismodule( obj ): if obj.__name__ in self.__already_imported: return False #do not check already imported modules source_file = self.getsourcefile(obj) if source_file: return contains_parent_dir( source_file, self.__include_paths ) else: return False obj_module = inspect.getmodule( obj ) if not obj_module is module: return False if inspect.isclass( obj ) \ or inspect.ismethod( obj ) \ or inspect.isfunction( obj ) \ or inspect.isroutine( obj ) \ or inspect.ismethoddescriptor( obj ) \ or inspect.isdatadescriptor( obj ): return True return False
def getMembers(cls): lfunctions = [] lmethods = [] lattributes = [] for m in inspect.getmembers(cls): m_name = m[0] m_object = m[1] if cls.__dict__.get(m_name): # Do not print inherited names #print(type(m_object)) if m_name[0] != "_" and m_name not in kobject.ignore_list: if inspect.isbuiltin(m_object): pass elif inspect.iscode(m_object): pass elif inspect.ismodule(m_object): pass elif inspect.ismethoddescriptor(m_object): pass elif inspect.isdatadescriptor(m_object): pass elif inspect.ismethod(m_object): lmethods.append(m) elif inspect.isfunction(m_object): lfunctions.append(m) elif inspect.isroutine(m_object): pass else: lattributes.append(m) return {"functions" : lfunctions, "methods" : lmethods, "attributes" : lattributes}
def print_variable_type(self, objType): default_vars=["__builtins__", "__doc__","__path__", "__cached__", "__file__", "__name__", "__package__", "__version__"] self.dprint("[ %s ]" %objType.__name__) self.indent();self.indent() for ModObj in self.Modules: for name in dir(ModObj): obj = getattr(ModObj, name) #print(name, ":", type(obj)) if not (inspect.isclass(obj) or inspect.isfunction(obj) or inspect.isroutine(obj) or inspect.isfunction(obj) or inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj) or inspect.istraceback(obj) or inspect.isframe(obj) or inspect.iscode(obj) or inspect.isabstract(obj) or inspect.ismethoddescriptor(obj) or inspect.isdatadescriptor(obj) or inspect.isgetsetdescriptor(obj) or inspect.ismemberdescriptor(obj) or inspect.isbuiltin(obj)): if name not in default_vars: if type(obj) is objType: ObjName = ModObj.__name__ + '.' + name self.dprint("%s" %ObjName) self.dedent();self.dedent()
def get_func_args(func, stripself=False): """Return the argument name list of a callable""" if inspect.isfunction(func): func_args, _, _, _ = inspect.getargspec(func) elif inspect.isclass(func): return get_func_args(func.__init__, True) elif inspect.ismethod(func): return get_func_args(func.__func__, True) elif inspect.ismethoddescriptor(func): return [] elif isinstance(func, partial): return [x for x in get_func_args(func.func)[len(func.args):] if not (func.keywords and x in func.keywords)] elif hasattr(func, '__call__'): if inspect.isroutine(func): return [] elif getattr(func, '__name__', None) == '__call__': return [] else: return get_func_args(func.__call__, True) else: raise TypeError('%s is not callable' % type(func)) if stripself: func_args.pop(0) return func_args
def getargspec(func, f): # Check if it's a real bound method or if it's implicitly calling __init__ # (i.e. FooClass(...) and not FooClass.__init__(...) -- the former would # not take 'self', the latter would: try: func_name = getattr(f, '__name__', None) except TypeError: return None try: is_bound_method = ((inspect.ismethod(f) and f.im_self is not None) or (func_name == '__init__' and not func.endswith('.__init__'))) except: # if f is a method from a xmlrpclib.Server instance, func_name == # '__init__' throws xmlrpclib.Fault (see #202) return None try: if PY3: argspec = inspect.getfullargspec(f) else: argspec = inspect.getargspec(f) argspec = list(argspec) fixlongargs(f, argspec) argspec = [func, argspec, is_bound_method] except (TypeError, KeyError): with AttrCleaner(f): argspec = getpydocspec(f, func) if argspec is None: return None if inspect.ismethoddescriptor(f): argspec[1][0].insert(0, 'obj') argspec.append(is_bound_method) return argspec
def _finddoc(obj): # type: (Any) -> unicode if inspect.isclass(obj): for base in obj.__mro__: if base is not object: try: doc = base.__doc__ except AttributeError: continue if doc is not None: return doc return None if inspect.ismethod(obj) and getattr(obj, '__self__', None): name = obj.__func__.__name__ self = obj.__self__ if (inspect.isclass(self) and getattr(getattr(self, name, None), '__func__') is obj.__func__): # classmethod cls = self else: cls = self.__class__ elif inspect.isfunction(obj) or inspect.ismethod(obj): name = obj.__name__ cls = _findclass(obj) if cls is None or getattr(cls, name) != obj: return None elif inspect.isbuiltin(obj): name = obj.__name__ self = obj.__self__ if (inspect.isclass(self) and self.__qualname__ + '.' + name == obj.__qualname__): # classmethod cls = self else: cls = self.__class__ # Should be tested before isdatadescriptor(). elif isinstance(obj, property): func = obj.fget name = func.__name__ cls = _findclass(func) if cls is None or getattr(cls, name) is not obj: return None elif inspect.ismethoddescriptor(obj) or inspect.isdatadescriptor(obj): name = obj.__name__ cls = obj.__objclass__ if getattr(cls, name) is not obj: return None else: return None for base in cls.__mro__: try: doc = getattr(base, name).__doc__ except AttributeError: continue if doc is not None: return doc return None
def attrfilter(attr): # Only add methods and attributes of the class to the CIX. # - "os._Environ" seems to be a particular problem case in that # some methods defined on it are inspect.ismethod() but not # inspect.ismethoddescriptor(). Not so for other examples in # modules that stdcix.py processes, and adding .ismethod() to this # filter adds unwanted methods on C-defined module exception # classes. if not (inspect.isdatadescriptor(attr) or inspect.ismethoddescriptor(attr) or inspect.ismethod(attr) or inspect.isfunction(attr)): return False # Skip inherited attributes in the CIX. try: attrname = attr.__name__ for base in obj.__bases__: if hasattr(base, attrname) and getattr(base, attrname) is \ getattr(obj, attrname): return False except AttributeError: # staticmethod and classmethod objects don't have a __name__ pass #print "Couldn't process: %r, assuming ok" % str(attr) return True
def get_scope_objects(names): """ Looks for the names defined with dir() in an objects and divides them into different object types. """ classes = {} funcs = {} stmts = {} members = {} for n in names: if '__' in n and n not in mixin_funcs: continue try: # this has a builtin_function_or_method exe = getattr(scope, n) except AttributeError: # happens e.g. in properties of # PyQt4.QtGui.QStyleOptionComboBox.currentText # -> just set it to None members[n] = None else: if inspect.isclass(scope): if is_in_base_classes(scope, n, exe): continue if inspect.isbuiltin(exe) or inspect.ismethod(exe) \ or inspect.ismethoddescriptor(exe): funcs[n] = exe elif inspect.isclass(exe): classes[n] = exe elif inspect.ismemberdescriptor(exe): members[n] = exe else: stmts[n] = exe return classes, funcs, stmts, members
def getAttributes(self): """See IClassDocumentation.""" return [ (name, obj, iface) for name, obj, iface in self._iterAllAttributes() if not (ismethod(obj) or ismethoddescriptor(obj)) ]
def _inspect_isroutine_override(object): import inspect return (isinstance(object, partial) or inspect.isbuiltin(object) or inspect.isfunction(object) or inspect.ismethod(object) or inspect.ismethoddescriptor(object))
def default(self, obj): if isinstance(obj, datetime): return self.default(date_time_2_millis(obj)) elif isinstance(obj, Enum): return self.default(obj.name) elif isinstance(obj, Color): return self.default(obj.hex()) elif hasattr(obj, "__dict__"): d = dict( (key, value) for key, value in inspect.getmembers(obj) if value is not None and not key == "Position" and not key.startswith("__") and not inspect.isabstract(value) and not inspect.isbuiltin(value) and not inspect.isfunction(value) and not inspect.isgenerator(value) and not inspect.isgeneratorfunction(value) and not inspect.ismethod(value) and not inspect.ismethoddescriptor(value) and not inspect.isroutine(value) ) return self.default(d) return obj
def get_cinspect_object(obj): """ Returns the object wrapped in the appropriate CInspectObject class. """ try: igetsource(obj) except (TypeError, IOError) as e: # The code to deal with this case is below pass else: return PythonObject(obj) if inspect.isbuiltin(obj): if obj.__module__ is None: # fixme: we could possibly check in `types` to see if it's really a # built-in... return BuiltinMethod(obj) else: # Any builtin/compiled functions ... return BuiltinFunction(obj) elif inspect.ismethoddescriptor(obj): return MethodDescriptor(obj) elif inspect.ismodule(obj): return Module(obj) elif inspect.isclass(obj): return Type(obj) elif inspect.isclass(type(obj)): return Type(obj.__class__) else: raise NotImplementedError
def getMethods(self): # remove the security proxy, so that `attr` is not proxied. We could # unproxy `attr` for each turn, but that would be less efficient. # # `getPermissionIds()` also expects the class's security checker not # to be proxied. klass = zope.security.proxy.removeSecurityProxy(self.klassView.context) obj = zope.security.proxy.removeSecurityProxy(self.context) for name in apidoc.utilities.getPublicAttributes(obj): val = getattr(obj, name) if not (inspect.ismethod(val) or inspect.ismethoddescriptor(val)): continue signature = apidoc.utilities.getFunctionSignature(val) entry = { 'name': name, 'signature': signature, 'doc': apidoc.utilities.renderText( val.__doc__ or '', getParent(self.klassView.context).getPath()), 'interface': apidoc.utilities.getInterfaceForAttribute( name, klass._Class__all_ifaces)} entry.update(apidoc.utilities.getPermissionIds( name, klass.getSecurityChecker())) yield entry
def _object_attributes(obj, parent): attributes = {} for name in dir(obj): if name == 'None': continue try: child = getattr(obj, name) except AttributeError: # descriptors are allowed to raise AttributeError # even if they are in dir() continue pyobject = None if inspect.isclass(child): pyobject = BuiltinClass(child, {}, parent=parent) elif inspect.isroutine(child): if inspect.ismethoddescriptor(child) and "__weakref__" in dir(obj): try: weak = child.__get__(obj.__weakref__.__objclass__()) except: weak = child pyobject = BuiltinFunction(builtin=weak, parent=parent) else: pyobject = BuiltinFunction(builtin=child, parent=parent) else: pyobject = BuiltinUnknown(builtin=child) attributes[name] = BuiltinName(pyobject) return attributes
def get_param_names(self): obj = self.obj try: if py_version < 33: raise ValueError("inspect.signature was introduced in 3.3") if py_version == 34: # In 3.4 inspect.signature are wrong for str and int. This has # been fixed in 3.5. The signature of object is returned, # because no signature was found for str. Here we imitate 3.5 # logic and just ignore the signature if the magic methods # don't match object. # 3.3 doesn't even have the logic and returns nothing for str # and classes that inherit from object. user_def = inspect._signature_get_user_defined_method if (inspect.isclass(obj) and not user_def(type(obj), '__init__') and not user_def(type(obj), '__new__') and (obj.__init__ != object.__init__ or obj.__new__ != object.__new__)): raise ValueError signature = inspect.signature(obj) except ValueError: # Has no signature params_str, ret = self._parse_function_doc() tokens = params_str.split(',') if inspect.ismethoddescriptor(obj): tokens.insert(0, 'self') for p in tokens: parts = p.strip().split('=') yield UnresolvableParamName(self, parts[0]) else: for signature_param in signature.parameters.values(): yield SignatureParamName(self, signature_param)
def _hook_tensor(self, tensor_type): """Overloading a given tensor_type""" # Overload 'special' methods here self._hook___new__(tensor_type) self._hook_tensor___repr__(tensor_type) self._hook_fixed_precision_methods(tensor_type) for attr in dir(tensor_type): # if we haven't already overloaded this function if 'old_{}'.format(attr) not in dir(tensor_type): # Conditions for inclusion/exclusion if attr in self.exclude: continue lit = getattr(tensor_type, attr) is_base = attr in dir(object) is_desc = inspect.ismethoddescriptor(lit) is_func = isinstance(lit, types.FunctionType) try: is_service_func = 'HookService' in lit.__qualname__ except: is_service_func = False is_old = re.match('old*', attr) is not None # Where the overloading happens if ((is_desc or (is_func and not is_service_func)) and not is_base and not is_old): passer = utils.pass_method_args(lit) new_attr = self._get_overload_method_in_tensor_or_var(passer) setattr(tensor_type, 'old_{}'.format(attr), lit) setattr(tensor_type, attr, new_attr) # Add in our own Grid-specific methods self._hook_send_(tensor_type) self._hook_get_(tensor_type) self._hook_tensor__serde(tensor_type)
def getAttributes(self): # remove the security proxy, so that `attr` is not proxied. We could # unproxy `attr` for each turn, but that would be less efficient. # # `getPermissionIds()` also expects the class's security checker not # to be proxied. klass = zope.security.proxy.removeSecurityProxy(self.klassView.context) obj = zope.security.proxy.removeSecurityProxy(self.context) for name in apidoc.utilities.getPublicAttributes(obj): value = getattr(obj, name) if inspect.ismethod(value) or inspect.ismethoddescriptor(value): continue entry = { 'name': name, 'value': `value`, 'value_linkable': IPhysicallyLocatable(value, False) and True, 'type': type(value).__name__, 'type_link': getTypeLink(type(value)), 'interface': apidoc.utilities.getInterfaceForAttribute( name, klass._Class__all_ifaces) } entry.update(apidoc.utilities.getPermissionIds( name, klass.getSecurityChecker())) yield entry
def _from_module(self, module, object): """ Return true if the given object is defined in the given module. """ if module is None: return True elif inspect.isfunction(object): return module.__dict__ is object.__globals__ elif inspect.isbuiltin(object): return module.__name__ == object.__module__ elif inspect.isclass(object): return module.__name__ == object.__module__ elif inspect.ismethod(object): # This one may be a bug in cython that fails to correctly set the # __module__ attribute of methods, but since the same error is easy # to make by extension code writers, having this safety in place # isn't such a bad idea return module.__name__ == object.__self__.__class__.__module__ elif inspect.getmodule(object) is not None: return module is inspect.getmodule(object) elif hasattr(object, '__module__'): return module.__name__ == object.__module__ elif isinstance(object, property): return True # [XX] no way not be sure. elif inspect.ismethoddescriptor(object): # Unbound PyQt signals reach this point in Python 3.4b3, and we want # to avoid throwing an error. See also http://bugs.python.org/issue3158 return False else: raise ValueError("object must be a class or function, got %r" % object)
def write_class(module, classname, classvalue): classes = [] methods = [] builtins = [] functions = [] methoddescs = [] others = [] theclass = '{0}.{1}'.format(module.__name__, classname) theclass = eval(theclass) for name, value in inspect.getmembers(theclass): if not isprivateobj(name): if inspect.isclass(value): classes.append((name, value)) elif inspect.ismethod(value): methods.append((name, value)) elif inspect.isfunction(value): functions.append((name, value)) elif inspect.isbuiltin(value): builtins.append((name, value)) elif inspect.ismethoddescriptor(value): methoddescs.append((name, value)) else: others.append((name, value)) if not others: members = [fmt_class_nomembers] else: members = [fmt_class_member.format(name=n, value=v) for n, v in others] s_classes = [fmt_class_class.format(classname=name, docstring=value.__doc__) \ for name, value in classes] s_methods = [fmt_class_method.format(methodname=name, docstring=value.__doc__) \ for name, value in (methods + functions + builtins + methoddescs)] out = fmt_class.format( modulename = module.__name__, classname = classname, docstring = theclass.__doc__, members = '\n'.join(members), classes = '\n'.join(s_classes), methods = '\n'.join(s_methods) ) mpath = modulepath(module) if not os.path.exists(mpath): os.makedirs(mpath) cfile = os.path.join(mpath, classname + '.py') try: with open(cfile, 'w') as f: f.write(out) f.close() print(cfile) except IOError: print "IOError"
def describe_module(module, kind, constants=[]): """ Describe the module object passed as argument including its classes and functions. """ module_name = module.__name__ if kind == object_types.LIBRARY: klass = Library(module_name) else: klass = Module(module_name, kind) klass.docs = getdoc(module) klass.comments = getcomments(module) klass.filename = module.__file__ inheritance_diagram = [] count = 0 for name in dir(module): if name in EXCLUDED_ATTRS: continue obj = getattr(module, name) if ismodule(obj): continue if ismemberdescriptor(obj) or isgetsetdescriptor(obj): continue if isclass(obj): count += 1 describe_class(obj, klass, module_name, constants) if obj.__module__ == module.__name__: inheritance_diagram.append(obj) elif isbuiltin(obj): count += 1 elif ismethod(obj) or isfunction(obj) or ismethoddescriptor(obj) or \ isinstance(obj, types.MethodType): count +=1 describe_func(obj, klass, module_name) else: attribute = Attribute(module_name + '.' + name, type(obj), obj) klass.Add(attribute) if constants: attribute.is_redundant = name not in constants if kind not in [object_types.PACKAGE, object_types.LIBRARY]: if inheritance_diagram and len(inheritance_diagram) < 20: klass.inheritance_diagram = inheritance.InheritanceDiagram(inheritance_diagram, klass) return klass, count
def get_param_names(self): params_str, ret = self._parse_function_doc() tokens = params_str.split(',') if inspect.ismethoddescriptor(self.obj): tokens.insert(0, 'self') for p in tokens: parts = p.strip().split('=') yield UnresolvableParamName(self, parts[0])
def _wrap_type_error_to_not_implemented(f): from torch import _six import inspect # functools.wraps doesn't work well with methods in python 2 method_assignments = ('__name__', '__doc__') assigned = (method_assignments if _six.PY2 and inspect.ismethoddescriptor(f) else functools.WRAPPER_ASSIGNMENTS) @functools.wraps(f, assigned=assigned) def wrapped(*args, **kwargs): try: return f(*args, **kwargs) except TypeError: return NotImplemented return wrapped
def default(self, obj): if isinstance(obj, datetime): return obj.isoformat() + 'Z' if hasattr(obj, "to_json"): return self.default(obj.to_json()) elif hasattr(obj, "__dict__"): d = dict( (key, value) for key, value in inspect.getmembers(obj) if not key.startswith("_") and not inspect.isabstract(value) and not inspect.isbuiltin(value) and not inspect.isfunction( value) and not inspect.isgenerator(value) and not inspect. isgeneratorfunction(value) and not inspect.ismethod(value) and not inspect.ismethoddescriptor(value) and not inspect.isroutine(value)) return self.default(d) return obj
def py__name__(self): if not _is_class_instance(self._obj) or \ inspect.ismethoddescriptor(self._obj): # slots cls = self._obj else: try: cls = self._obj.__class__ except AttributeError: # happens with numpy.core.umath._UFUNC_API (you get it # automatically by doing `import numpy`. return None try: return force_unicode(cls.__name__) except AttributeError: return None
def process_class(rootElt, obj, name, callables, __hidden__=False): doc = getsdoc(obj) or None classElt = SubElement(rootElt, "scope", ilk="class", name=name) if doc: classElt.set('doc', doc) callables[name] = classElt if __hidden__: classElt.set('attributes', '__hidden__') classrefs = [base.__name__ for base in obj.__bases__] if classrefs: classElt.set('classrefs', ' '.join(classrefs)) # Functions are method descriptors in Python inspect module parlance. def attrfilter(attr): # Only add methods and attributes of the class to the CIX. # - "os._Environ" seems to be a particular problem case in that # some methods defined on it are inspect.ismethod() but not # inspect.ismethoddescriptor(). Not so for other examples in # modules that stdcix.py processes, and adding .ismethod() to this # filter adds unwanted methods on C-defined module exception # classes. if not (inspect.isdatadescriptor(attr) or inspect.ismethoddescriptor(attr) or inspect.ismethod(attr) or inspect.isfunction(attr)): return False # Skip inherited attributes in the CIX. try: attrname = attr.__name__ for base in obj.__bases__: if hasattr(base, attrname) and getattr(base, attrname) is \ getattr(obj, attrname): return False except AttributeError: # staticmethod and classmethod objects don't have a __name__ pass # print "Couldn't process: %r, assuming ok" % str(attr) return True # attrs = inspect.getmembers(object, attrfilter) # should I be using # getmembers or class attr's? attrs = [(name, getattr( obj, name)) for name in obj.__dict__ if name not in ('__abstractmethods__')] attrs = [(name, attr) for (name, attr) in attrs if attrfilter(attr)] for (key, value) in attrs: if inspect.isfunction(value) or inspect.ismethod(value) or inspect.ismethoddescriptor(value): process_routine(classElt, value, key, callables)
def inject_globals(func, vrbls): "Inject user-defined variables into the function's globals." # We can have callables which aren't methods or functions, such as # class instances, so allow to loop twice. On the first pass we # discover that we don't have a normal callable and set func to # the __call__ attribute of that object. On the second pass, it # better be one of the other things we know how to handle # directly. # # I suppose you could have something like this: # # class C(object): # def __call__(self): # print("called") # # class Other(object): # c = C() # __call__ = c # # o = Other() # # (or something like that). In this case, if o was the callable, # you'd discover that o has a __call__ method, then need to go # through the entire exercise again, because c.__call__ is itself # not a normal function-like beast. for _i in (0, 1): if inspect.ismethod(func): func_globals = func.__func__.__globals__ elif inspect.isfunction(func): func_globals = func.__globals__ elif inspect.isbuiltin(func): func_globals = sys.modules[func.__module__].__dict__ elif inspect.ismethoddescriptor(func): raise TypeError("Can't get globals of a method descriptor") elif hasattr(func, "__call__"): func = func.__call__ # Try again... continue else: raise TypeError("Don't know how to find globals from %s objects" % type(func)) break else: raise TypeError("Don't know how to find globals from %s objects" % type(func)) func_globals.update(vrbls)
def _get_method(cls, name): """Introspect a class for a method and its kind. This is copied from the heart of inspect.classify_class_attrs(), with the difference that we're only concerned about a single attribute of the class. """ mro = inspect.getmro(cls) # Try to get it from the class dict if name in cls.__dict__: raw_obj = cls.__dict__[name] else: raw_obj = getattr(cls, name) # Figure out where it came from homecls = getattr(raw_obj, "__objclass__", None) if homecls is None: # Search the dicts for base in mro: if name in base.__dict__: homecls = base break # Get the object again, in order to get it from the __dict__ # instead of via getattr (if possible) if homecls is not None and name in homecls.__dict__: raw_obj = homecls.__dict__[name] # Also get via getattr obj = getattr(cls, name) # Classify the object if isinstance(raw_obj, staticmethod) or name == '__new__': kind = "static method" elif isinstance(raw_obj, classmethod): kind = "class method" elif isinstance(raw_obj, property): kind = "property" elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): kind = "method" else: kind = "data" # Return the object and its kind return obj, raw_obj, kind
def __init__(self, backend, mangler, ttl, callable, **kwargs): self._backend = backend self._mangler = mangler self._ttl = ttl self._keyFunc = kwargs.get('key', self._mangler.nameEntry) self._tags = kwargs.get('tags', None) self._callable = callable self._isDescriptor = inspect.ismethoddescriptor(callable) self._isMethod = inspect.ismethod(callable) # preserve ``__name__``, ``__doc__``, etc try: functools.update_wrapper(self, callable) except AttributeError: # Python 2 doesn't skip missing attributes pass
def assertFunctionDefined(self, obj: Union[ModuleType, Type], function_name: str, params: int): self.assertDefined(obj, function_name) obj_name = get_object_name(obj) func = getattr(obj, function_name) if not inspect.isfunction(func): if inspect.ismethoddescriptor(func): self.fail( msg=f"{obj_name}.{function_name} needs to be implemented") self.fail(msg=f"{obj_name}.{function_name} should be a function") num_params = len(inspect.signature(func).parameters) self.assertEqual( num_params, params, msg= (f"'{function_name}' does not have the correct number of parameters, " f"expected {params} found {num_params}"))
def getMethods(self, object, class_name): try: key = "%s:%s" % (self.module_name, class_name) blacklist = BLACKLIST[key] except KeyError: blacklist = set() methods = [] for name in dir(object): if name in blacklist: continue if SKIP_PRIVATE and name.startswith("__"): continue attr = getattr(object, name) if not ismethoddescriptor(attr): continue methods.append(name) return methods
def taint_class(klass, methods): class tklass(klass): def __new__(cls, *args, **kwargs): self = super(tklass, cls).__new__(cls, *args, **kwargs) self.taints = set() return self d = klass.__dict__ for name, attr in [(m, d[m]) for m in methods]: if inspect.ismethod(attr) or inspect.ismethoddescriptor(attr): setattr(tklass, name, propagate_method(attr)) # str has no __radd__ method, it does if '__add__' in methods and '__radd__' not in methods: setattr(tklass, '__radd__', lambda self, other: tklass.__add__(tklass(other), self)) return tklass
def default(self, obj): if hasattr(obj, 'to_json'): return self.default(obj.to_json()) elif hasattr(obj, '__dict__'): d = dict( (key, value) for key, value in inspect.getmembers(obj) if not key.startswith('__') and not inspect.isabstract(value) and not inspect.isbuiltin(value) and not inspect.isfunction(value) and not inspect.isgenerator(value) and not inspect.isgeneratorfunction(value) and not inspect.ismethod(value) and not inspect.ismethoddescriptor(value) and not inspect.isroutine(value) ) return self.default(d) return obj
def is_method(func: Callable[..., Any]) -> bool: ''' Checks whether a function is a method Parameters ---------- func : TYPE The function to check Returns ------- bool Whether the function stifies the conditions ''' return (inspect.ismethod(func) or inspect.ismethoddescriptor(func) or has_self_parameter(func))
def __getattribute__(self, name, prototypes=None): if name.startswith("_") and name not in ('__init__', '__new__'): return __get__(self, name) for this in prototypes or self._prototypes: try: attribute = this.__dict__[name] if isinstance( this, prototype) else __get__(this, name) except (KeyError, AttributeError): continue if ismethoddescriptor(attribute): attribute = attribute.__get__(this) if isfunction( attribute ) and attribute.__name__ != '__new__': # new is always static return MethodType(attribute, selftype(self, this, self)) return attribute raise AttributeError(name)
def default(self, obj): # if hasattr(obj, "to_json"): # return self.default(obj.to_json()) if isinstance(obj, Enum): return obj.name elif hasattr(obj, "__dict__"): d = dict( (key, value) for key, value in inspect.getmembers(obj) if not key.startswith("__") and not inspect.isabstract(value) and not inspect.isbuiltin(value) and not inspect.isfunction( value) and not inspect.isgenerator(value) and not inspect. isgeneratorfunction(value) and not inspect.ismethod(value) and not inspect.ismethoddescriptor(value) and not inspect.isroutine(value) and not self.isempty(value) and not value is None) return self.default(d) return obj
def ismethoddescriptor(self): """Return true if the object is a method descriptor, but not if ismethod() or isclass() or isfunction() are true. This is new as of Python 2.2, and, for example, is true of int.__add__. An object passing this test has a __get__ attribute but not a __set__ attribute, but beyond that the set of attributes varies. __name__ is usually sensible, and __doc__ often is. Methods implemented via descriptors that also pass one of the other tests return false from the ismethoddescriptor() test, simply because the other tests promise more - you can, e.g., count on having the im_func attribute (etc) when an object passes ismethod(). """ return inspect.ismethoddescriptor(self.obj)
def verify_overloadedfuncdef( stub: nodes.OverloadedFuncDef, runtime: MaybeMissing[Any], object_path: List[str] ) -> Iterator[Error]: if isinstance(runtime, Missing): yield Error(object_path, "is not present at runtime", stub, runtime) return if stub.is_property: # We get here in cases of overloads from property.setter return if ( not isinstance(runtime, (types.FunctionType, types.BuiltinFunctionType)) and not isinstance(runtime, (types.MethodType, types.BuiltinMethodType)) and not inspect.ismethoddescriptor(runtime) ): yield Error(object_path, "is not a function", stub, runtime) if not callable(runtime): return for message in _verify_static_class_methods(stub, runtime, object_path): yield Error(object_path, "is inconsistent, " + message, stub, runtime) try: signature = inspect.signature(runtime) except ValueError: return stub_sig = Signature.from_overloadedfuncdef(stub) runtime_sig = Signature.from_inspect_signature(signature) for message in _verify_signature(stub_sig, runtime_sig, function_name=stub.name): # TODO: This is a little hacky, but the addition here is super useful if "has a default value of type" in message: message += ( ". This is often caused by overloads failing to account for explicitly passing " "in the default value." ) yield Error( object_path, "is inconsistent, " + message, stub, runtime, stub_desc=str(stub.type) + "\nInferred signature: {}".format(stub_sig), runtime_desc="def " + str(signature), )
def default(self, obj): if hasattr(obj, "to_json"): print("f*****g 0") return self.default(obj.to_json()) elif hasattr(obj, "__dict__"): d = dict( (key, value) for key, value in inspect.getmembers(obj) if not key.startswith("__") and not inspect.isabstract(value) and not inspect.isbuiltin(value) and not inspect.isfunction( value) and not inspect.isgenerator(value) and not inspect. isgeneratorfunction(value) and not inspect.ismethod(value) and not inspect.ismethoddescriptor(value) and not inspect.isroutine(value)) print("f*****g A") return self.default(d) print("f*****g C") return obj
def __getitem__(self, key): try: return self._mapping[key] except KeyError: prop = vars(self.__class__)[key] # Expose non-private descriptors via mapping interface. It turns # out all objects have private (dunder) descriptors and since it's # not something the can be defined by a user, we don't really want # to expose them. if not key.startswith("_") and ( inspect.isdatadescriptor(prop) or inspect.ismethoddescriptor(prop) ): return getattr(self, key) raise
def format_signature(what, obj): """Return the signature of the object, formatted for display.""" if what not in ('class', 'method', 'function'): return '' if what == 'class': # for classes, the relevant signature is the __init__ method's obj = getattr(obj, '__init__', None) # classes without __init__ method? if obj is None or obj is object.__init__: return '' if inspect.isbuiltin(obj) or inspect.ismethoddescriptor(obj): return '' argspec = inspect.getargspec(obj) if what in ('class', 'method') and argspec[0] and \ argspec[0][0] in ('cls', 'self'): del argspec[0][0] return inspect.formatargspec(*argspec)
def taint_class(klass, methods=None): if not methods: methods = attributes(klass) class tklass(klass): def __new__(cls, *args, **kwargs): self = super(tklass, cls).__new__(cls, *args, **kwargs) #justificar analizar pq no init self.taints = set() # if any of the arguments is tainted, taint the object aswell for a in args: # this CHUNK of code appears at least 3 times, refactor later collect_tags(a, self.taints) for v in kwargs.values(): collect_tags(v, self.taints) return self # support for assigment and taint change in classobj def __setattr__(self, name, value): if self.__dict__ and name in self.__dict__ and tainted(self.__dict__[name]): for t in self.__dict__[name].taints: # if other field had it, keep it taintsets = [v.taints for k,v in self.__dict__.items() if not callable(v) and tainted(v) and k != name] if not any([t in x for x in taintsets]): self.taints.remove(t) if self.__dict__ is not None: self.__dict__[name] = value if tainted(value): self.taints.update(value.taints) d = klass.__dict__ for name, attr in [(m, d[m]) for m in methods]: if inspect.ismethod(attr) or inspect.ismethoddescriptor(attr): setattr(tklass, name, propagate_method(attr)) # str has no __radd__ method if '__add__' in methods and '__radd__' not in methods: setattr(tklass, '__radd__', lambda self, other: tklass.__add__(tklass(other), self)) # unicode __rmod__ returns NotImplemented if klass == unicode: setattr(tklass, '__rmod__', lambda self, other: tklass.__mod__(tklass(other), self)) return tklass
def _write_class(clss, lines, inc = 0, assumed_globals=None, implicit_globals=None, assumed_typevars=None): _print("write class: "+str(clss)) anyElement = False lines.append(inc*indent+typelogger._signature_class(clss, assumed_globals, implicit_globals, assumed_typevars)) mb = inspect.getmembers(clss, lambda t: inspect.isclass(t) or type_util._check_as_func(t)) # todo: Care for overload-decorator for elem in mb: if elem[0] in clss.__dict__: el = clss.__dict__[elem[0]] if inspect.isfunction(el): lines.append('') _write_func(el, lines, inc+1, slf_or_clsm=True, assumed_globals=assumed_globals) anyElement = True elif inspect.isclass(el): lines.append('') if isinstance(el, TypeVar): _write_TypeVar(el, lines, inc+1) else: _write_class(el, lines, inc+1, assumed_globals, implicit_globals, assumed_typevars) anyElement = True elif inspect.ismethoddescriptor(el) and type(el) is staticmethod: lines.append('') _write_func(el.__func__, lines, inc+1, ['staticmethod'], assumed_globals=assumed_globals) anyElement = True elif isinstance(el, property): lines.append('') _write_property(el, lines, inc+1, assumed_globals=assumed_globals) anyElement = True # classmethods are not obtained via inspect.getmembers. # We have to look into __dict__ for that. for key in clss.__dict__: attr = getattr(clss, key) if inspect.ismethod(attr): lines.append('') _write_func(attr, lines, inc+1, ['classmethod'], True, assumed_globals) anyElement = True if not anyElement: lines.append((inc+1)*indent+'pass')
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 for_object_list(object, type): ''' For a given object inspects it for the existence of named instance/class/static method, property, and data element (global or attribute) attribute; and returns in tuple form (kind, obj, homeClass) ''' value = [] names = dir(object) for name in names: if name in object.__dict__: obj = object.__dict__[name] else: obj = getattr(object, name) homeClass = getattr(obj, "__objclass__", None) if homeClass is None: for base in inspect.getmro(object): if name in base.__dict__: homeClass = base break if ((homeClass is not None) and (name in homeClass.__dict__)): obj = homeClass.__dict__[name] obj_via_getattr = getattr(object, name) if isinstance(obj, staticmethod): kind = staticmethod elif isinstance(obj, classmethod): kind = CLASS_METHOD elif isinstance(obj, property): kind = PROPERTY elif (inspect.ismethod(obj_via_getattr) or inspect.ismethoddescriptor(obj_via_getattr)): kind = INSTANCE_METHOD else: kind = DATA print name, kind, obj if (kind is type): value.append(name) return value
def inspect_class_for_attribute(klazz, name): ''' For a given class inspects it for the existence of named instance/class/static method, property, and data element (global or attribute) attribute; and returns in tuple form (kind, obj, homeClass) ''' if inspect.isclass(klazz): if name in dir(klazz): if name in klazz.__dict__: obj = klazz.__dict__[name] else: obj = getattr(klazz, name) homeClass = getattr(obj, "__objclass__", None) if homeClass is None: for base in inspect.getmro(klazz): if name in base.__dict__: homeClass = base break if ((homeClass is not None) and (name in homeClass.__dict__)): obj = homeClass.__dict__[name] obj_via_getattr = getattr(klazz, name) if isinstance(obj, staticmethod): kind = staticmethod elif isinstance(obj, classmethod): kind = CLASS_METHOD elif isinstance(obj, property): kind = PROPERTY elif (inspect.ismethod(obj_via_getattr) or inspect.ismethoddescriptor(obj_via_getattr)): kind = INSTANCE_METHOD else: kind = DATA return (kind, obj, homeClass) else: return (None, None, None) else: raise TypeError( "parameter 'klazz' must a class object, not an instance of a class." )
def _get_callable_fq_for_code(code, module_or_class, module, slf, nesting): keys = [key for key in module_or_class.__dict__] for key in keys: slf2 = slf obj = module_or_class.__dict__[key] if inspect.isfunction(obj) or inspect.ismethod(obj) \ or inspect.ismethoddescriptor(obj) or isinstance(obj, property): if isinstance(obj, classmethod) or isinstance(obj, staticmethod): obj = obj.__func__ slf2 = False elif isinstance(obj, property): slf2 = True if not obj.fset is None: try: if obj.fset.__module__ == module.__name__ and \ _code_matches_func(obj.fset, code): return getattr(module_or_class, key), slf2 except AttributeError: try: if obj.fset.__func__.__module__ == module.__name__ and \ _code_matches_func(obj.fset, code): return getattr(module_or_class, key), slf2 except AttributeError: pass obj = obj.fget try: if obj.__module__ == module.__name__ and _code_matches_func( obj, code): return getattr(module_or_class, key), slf2 except AttributeError: try: if obj.__func__.__module__ == module.__name__ and \ _code_matches_func(obj, code): return getattr(module_or_class, key), slf2 except AttributeError: pass elif inspect.isclass(obj) and obj.__module__ == module.__name__: nesting.append(obj) res, slf2 = _get_callable_fq_for_code(code, obj, module, True, nesting) if not res is None: return res, slf2 else: nesting.pop() return None, False
def patch_object(obj): """ Applies func:`encode_decode` decorator to an object :param obj: object for patching :return: patched object """ if inspect.isbuiltin(obj): obj = encode_decode(obj) elif inspect.isclass(obj): # We cannot patch methods of Kodi classes directly. obj = _wrap_class(obj) for memb_name, member in inspect.getmembers(obj): # Do not patch special methods! if (inspect.ismethoddescriptor(member) and not memb_name.endswith('__')): setattr(obj, memb_name, encode_decode(member)) return obj
def format_args(self): if inspect.isbuiltin(self.object) or \ inspect.ismethoddescriptor(self.object): # can never get arguments of a C function or method return None try: argspec = inspect.getargspec(self.object) except TypeError: # if a class should be documented as function (yay duck # typing) we try to use the constructor signature as function # signature without the first argument. try: argspec = inspect.getargspec(self.object.__new__) except TypeError: argspec = inspect.getargspec(self.object.__init__) if argspec[0]: del argspec[0][0] return inspect.formatargspec(*argspec)
def args_on_obj(obj): if hasattr(obj, "_sage_argspec_"): argspec = obj._sage_argspec_() elif inspect.isbuiltin(obj) or inspect.ismethoddescriptor(obj): # can never get arguments of a C function or method unless # a function to do so is supplied if self.env.config.autodoc_builtin_argspec: argspec = self.env.config.autodoc_builtin_argspec(obj) else: return None else: # The check above misses ordinary Python methods in Cython # files. argspec = sage_getargspec(obj) #inspect.getargspec(obj) #if isclassinstance(obj) or inspect.isclass(obj): if argspec is not None and argspec[0] and argspec[0][0] in ('cls', 'self'): del argspec[0][0] return argspec
def visit_member(parent_name, member): cur_name = ".".join([parent_name, member.__name__]) if inspect.isclass(member): queue_dict(member, cur_name) for name, value in inspect.getmembers(member): if hasattr(value, '__name__') and (not name.startswith("_") or name == "__init__"): visit_member(cur_name, value) elif inspect.ismethoddescriptor(member): return elif callable(member): queue_dict(member, cur_name) elif inspect.isgetsetdescriptor(member): return else: raise RuntimeError( "Unsupported generate signature of member, type {0}".format( str(type(member))))
def is_data_attr(name, attr, exclude_special=True): """ Return true if the given attribute is a data attribute, e.g. not a method or an inner class. Many data attributes are properties. By default, attributes with double-underscore names (e.g. :attr:`__dict__`) are not considered data attributes. Unlike special methods, these "special attributes" are very rarely relevant to users of a class. This behavior can be disabled by toggling the *exclude_special* argument. """ if exclude_special and is_special(name): return False return all([ not inspect.isclass(attr), not inspect.isfunction(attr), not inspect.ismethoddescriptor(attr), ])