def visit_getattr(self, node): """check that the accessed attribute exists to avoid to much false positives for now, we'll consider the code as correct if a single of the infered nodes has the accessed attribute. function/method, super call and metaclasses are ignored """ if node.attrname in self.config.generated_members: # attribute is marked as generated, stop here return try: infered = list(node.expr.infer()) except astng.InferenceError: return # list of (node, nodename) which are missing the attribute missingattr = set() ignoremim = self.config.ignore_mixin_members inference_failure = False for owner in infered: # skip yes object if owner is astng.YES: inference_failure = True continue # skip None anyway if isinstance(owner, astng.Const) and owner.value is None: continue # XXX "super" / metaclass call if is_super(owner) or getattr(owner, 'type', None) == 'metaclass': continue name = getattr(owner, 'name', 'None') if name in self.config.ignored_classes: continue if ignoremim and name[-5:].lower() == 'mixin': continue try: owner.getattr(node.attrname) except AttributeError: # XXX method / function continue except astng.NotFoundError, ex: if isinstance(owner, astng.Instance) \ and owner.has_dynamic_getattr(): continue # explicit skipping of optparse'Values class if owner.name == 'Values' and \ owner.root().name in ('optik', 'optparse'): continue missingattr.add((owner, name)) continue # stop on the first found break
def _emit_no_member(owner, owner_name, attrname, ignored_modules, ignored_mixins, ignored_classes): """Try to see if no-member should be emitted for the given owner. The following cases are ignored: * the owner is a function and it has decorators. * the owner is an instance and it has __getattr__, __getattribute__ implemented * the module is explicitly ignored from no-member checks * the owner is a class and the name can be found in its metaclass. """ if owner_name in ignored_classes: return False # skip None anyway if isinstance(owner, astroid.Const) and owner.value is None: return False # TODO(cpopa): This should be removed when we'll understand "super" if is_super(owner) or getattr(owner, 'type', None) == 'metaclass': return False if ignored_mixins and owner_name[-5:].lower() == 'mixin': return False if isinstance(owner, astroid.Function) and owner.decorators: return False if isinstance(owner, Instance): if owner.has_dynamic_getattr() or not has_known_bases(owner): return False # explicit skipping of module member access if owner.root().name in ignored_modules: return False if isinstance(owner, astroid.Class): # Look up in the metaclass only if the owner is itself # a class. # TODO: getattr doesn't return by default members # from the metaclass, because handling various cases # of methods accessible from the metaclass itself # and/or subclasses only is too complicated for little to # no benefit. metaclass = owner.metaclass() or owner.implicit_metaclass() try: if metaclass and metaclass.getattr(attrname): return False except NotFoundError: pass return True
def _emit_no_member(node, owner, owner_name, ignored_mixins): """Try to see if no-member should be emitted for the given owner. The following cases are ignored: * the owner is a function and it has decorators. * the owner is an instance and it has __getattr__, __getattribute__ implemented * the module is explicitly ignored from no-member checks * the owner is a class and the name can be found in its metaclass. * The access node is protected by an except handler, which handles AttributeError, Exception or bare except. """ if node_ignores_exception(node, AttributeError): return False # skip None anyway if isinstance(owner, astroid.Const) and owner.value is None: return False if is_super(owner) or getattr(owner, 'type', None) == 'metaclass': return False if ignored_mixins and owner_name[-5:].lower() == 'mixin': return False if isinstance(owner, astroid.FunctionDef) and owner.decorators: return False if isinstance(owner, astroid.Instance): if owner.has_dynamic_getattr() or not has_known_bases(owner): return False if isinstance(owner, objects.Super): # Verify if we are dealing with an invalid Super object. # If it is invalid, then there's no point in checking that # it has the required attribute. Also, don't fail if the # MRO is invalid. try: owner.super_mro() except (exceptions.MroError, exceptions.SuperError): return False if not all(map(has_known_bases, owner.type.mro())): return False return True
def _emit_no_member(node, owner, owner_name, ignored_mixins): """Try to see if no-member should be emitted for the given owner. The following cases are ignored: * the owner is a function and it has decorators. * the owner is an instance and it has __getattr__, __getattribute__ implemented * the module is explicitly ignored from no-member checks * the owner is a class and the name can be found in its metaclass. * The access node is protected by an except handler, which handles AttributeError, Exception or bare except. """ if node_ignores_exception(node, AttributeError): return False # skip None anyway if isinstance(owner, astroid.Const) and owner.value is None: return False if is_super(owner) or getattr(owner, "type", None) == "metaclass": return False if ignored_mixins and owner_name[-5:].lower() == "mixin": return False if isinstance(owner, astroid.FunctionDef) and owner.decorators: return False if isinstance(owner, astroid.Instance): if owner.has_dynamic_getattr() or not has_known_bases(owner): return False if isinstance(owner, objects.Super): # Verify if we are dealing with an invalid Super object. # If it is invalid, then there's no point in checking that # it has the required attribute. Also, don't fail if the # MRO is invalid. try: owner.super_mro() except (exceptions.MroError, exceptions.SuperError): return False if not all(map(has_known_bases, owner.type.mro())): return False return True
def visit_getattr(self, node): """check that the accessed attribute exists to avoid to much false positives for now, we'll consider the code as correct if a single of the inferred nodes has the accessed attribute. function/method, super call and metaclasses are ignored """ # generated_members may containt regular expressions # (surrounded by quote `"` and followed by a comma `,`) # REQUEST,aq_parent,"[a-zA-Z]+_set{1,2}"' => # ('REQUEST', 'aq_parent', '[a-zA-Z]+_set{1,2}') if isinstance(self.config.generated_members, str): gen = shlex.shlex(self.config.generated_members) gen.whitespace += ',' gen.wordchars += '[]-+' self.config.generated_members = tuple(tok.strip('"') for tok in gen) for pattern in self.config.generated_members: # attribute is marked as generated, stop here if re.match(pattern, node.attrname): return try: infered = list(node.expr.infer()) except InferenceError: return # list of (node, nodename) which are missing the attribute missingattr = set() ignoremim = self.config.ignore_mixin_members inference_failure = False for owner in infered: # skip yes object if owner is YES: inference_failure = True continue # skip None anyway if isinstance(owner, astroid.Const) and owner.value is None: continue # XXX "super" / metaclass call if is_super(owner) or getattr(owner, 'type', None) == 'metaclass': continue name = getattr(owner, 'name', 'None') if name in self.config.ignored_classes: continue if ignoremim and name[-5:].lower() == 'mixin': continue try: if not [n for n in owner.getattr(node.attrname) if not isinstance(n.statement(), astroid.AugAssign)]: missingattr.add((owner, name)) continue except AttributeError: # XXX method / function continue except NotFoundError: if isinstance(owner, astroid.Function) and owner.decorators: continue if isinstance(owner, Instance) and owner.has_dynamic_getattr(): continue # explicit skipping of module member access if owner.root().name in self.config.ignored_modules: continue missingattr.add((owner, name)) continue # stop on the first found break else: # we have not found any node with the attributes, display the # message for infered nodes done = set() for owner, name in missingattr: if isinstance(owner, Instance): actual = owner._proxied else: actual = owner if actual in done: continue done.add(actual) if inference_failure: msgid = 'maybe-no-member' else: msgid = 'no-member' self.add_message(msgid, node=node, args=(owner.display_type(), name, node.attrname))
def visit_getattr(self, node): """check that the accessed attribute exists to avoid to much false positives for now, we'll consider the code as correct if a single of the infered nodes has the accessed attribute. function/method, super call and metaclasses are ignored """ if node.attrname in self.config.generated_members: # attribute is marked as generated, stop here return try: infered = list(node.expr.infer()) except InferenceError: return # list of (node, nodename) which are missing the attribute missingattr = set() ignoremim = self.config.ignore_mixin_members inference_failure = False for owner in infered: # skip yes object if owner is YES: inference_failure = True continue # skip None anyway if isinstance(owner, astng.Const) and owner.value is None: continue # XXX "super" / metaclass call if is_super(owner) or getattr(owner, 'type', None) == 'metaclass': continue name = getattr(owner, 'name', 'None') if name in self.config.ignored_classes: continue if ignoremim and name[-5:].lower() == 'mixin': continue try: if not [n for n in owner.getattr(node.attrname) if not isinstance(n.statement(), astng.AugAssign)]: missingattr.add((owner, name)) continue except AttributeError: # XXX method / function continue except NotFoundError: if isinstance(owner, Instance) and owner.has_dynamic_getattr(): continue # explicit skipping of optparse'Values class if owner.name == 'Values' and \ owner.root().name in ('optik', 'optparse'): continue missingattr.add((owner, name)) continue # stop on the first found break else: # we have not found any node with the attributes, display the # message for infered nodes done = set() for owner, name in missingattr: if isinstance(owner, Instance): actual = owner._proxied else: actual = owner if actual in done: continue done.add(actual) if inference_failure: msgid = 'E1103' else: msgid = 'E1101' self.add_message(msgid, node=node, args=(display_type(owner), name, node.attrname))
def visit_getattr(self, node): """check that the accessed attribute exists to avoid to much false positives for now, we'll consider the code as correct if a single of the inferred nodes has the accessed attribute. function/method, super call and metaclasses are ignored """ if node.attrname in self.generated_members: # attribute is marked as generated, stop here return try: infered = list(node.expr.infer()) except InferenceError: return # list of (node, nodename) which are missing the attribute missingattr = set() ignoremim = self.config.ignore_mixin_members inference_failure = False for owner in infered: # skip yes object if owner is YES: inference_failure = True continue # skip None anyway if isinstance(owner, astng.Const) and owner.value is None: continue # XXX "super" / metaclass call if is_super(owner) or getattr(owner, 'type', None) == 'metaclass': continue name = getattr(owner, 'name', 'None') if name in self.config.ignored_classes: continue if ignoremim and name[-5:].lower() == 'mixin': continue try: if not [n for n in owner.getattr(node.attrname) if not isinstance(n.statement(), astng.AugAssign)]: missingattr.add((owner, name)) continue except AttributeError: # XXX method / function continue except NotFoundError: if isinstance(owner, Instance) and owner.has_dynamic_getattr(): continue # explicit skipping of optparse'Values class if owner.name == 'Values' and owner.root().name == 'optparse': continue missingattr.add((owner, name)) continue # stop on the first found break else: # we have not found any node with the attributes, display the # message for infered nodes done = set() for owner, name in missingattr: if isinstance(owner, Instance): actual = owner._proxied else: actual = owner if actual in done: continue done.add(actual) if inference_failure: msgid = 'E1103' else: msgid = 'E1101' self.add_message(msgid, node=node, args=(owner.display_type(), name, node.attrname))
def visit_getattr(self, node): """check that the accessed attribute exists to avoid to much false positives for now, we'll consider the code as correct if a single of the inferred nodes has the accessed attribute. function/method, super call and metaclasses are ignored """ # generated_members may containt regular expressions # (surrounded by quote `"` and followed by a comma `,`) # REQUEST,aq_parent,"[a-zA-Z]+_set{1,2}"' => # ('REQUEST', 'aq_parent', '[a-zA-Z]+_set{1,2}') if isinstance(self.config.generated_members, str): gen = shlex.shlex(self.config.generated_members) gen.whitespace += "," gen.wordchars += "[]-+" self.config.generated_members = tuple(tok.strip('"') for tok in gen) for pattern in self.config.generated_members: # attribute is marked as generated, stop here if re.match(pattern, node.attrname): return try: infered = list(node.expr.infer()) except InferenceError: return # list of (node, nodename) which are missing the attribute missingattr = set() ignoremim = self.config.ignore_mixin_members inference_failure = False for owner in infered: # skip yes object if owner is YES: inference_failure = True continue # skip None anyway if isinstance(owner, astroid.Const) and owner.value is None: continue # XXX "super" / metaclass call if is_super(owner) or getattr(owner, "type", None) == "metaclass": continue name = getattr(owner, "name", "None") if name in self.config.ignored_classes: continue if ignoremim and name[-5:].lower() == "mixin": continue try: if not [n for n in owner.getattr(node.attrname) if not isinstance(n.statement(), astroid.AugAssign)]: missingattr.add((owner, name)) continue except AttributeError: # XXX method / function continue except NotFoundError: if isinstance(owner, astroid.Function) and owner.decorators: continue if isinstance(owner, Instance) and owner.has_dynamic_getattr(): continue # explicit skipping of module member access if owner.root().name in self.config.ignored_modules: continue if isinstance(owner, astroid.Class): # Look up in the metaclass only if the owner is itself # a class. # TODO: getattr doesn't return by default members # from the metaclass, because handling various cases # of methods accessible from the metaclass itself # and/or subclasses only is too complicated for little to # no benefit. metaclass = owner.metaclass() try: if metaclass and metaclass.getattr(node.attrname): continue except NotFoundError: pass missingattr.add((owner, name)) continue # stop on the first found break else: # we have not found any node with the attributes, display the # message for infered nodes done = set() for owner, name in missingattr: if isinstance(owner, Instance): actual = owner._proxied else: actual = owner if actual in done: continue done.add(actual) confidence = INFERENCE if not inference_failure else INFERENCE_FAILURE self.add_message( "no-member", node=node, args=(owner.display_type(), name, node.attrname), confidence=confidence )