Beispiel #1
0
 def get_special_attribute(self, node, name, valself):
     # Based on the definitions of object_init and object_new in
     # cpython/Objects/typeobject.c (https://goo.gl/bTEBRt). It is legal to pass
     # extra arguments to object.__new__ if the calling class overrides
     # object.__init__, and vice versa.
     if valself and not abstract_utils.equivalent_to(valself, self):
         val = valself.data
         if name == "__new__" and self._has_own(node, val, "__init__"):
             self.load_lazy_attribute("__new__extra_args")
             return self.members["__new__extra_args"]
         elif (name == "__init__" and isinstance(val, abstract.Instance)
               and self._has_own(node, val.cls, "__new__")):
             self.load_lazy_attribute("__init__extra_args")
             return self.members["__init__extra_args"]
     return super().get_special_attribute(node, name, valself)
Beispiel #2
0
 def _get_class_attribute(self, node, cls, name, valself=None):
     """Get an attribute from a class."""
     assert isinstance(cls, mixin.Class)
     if (not valself or not abstract_utils.equivalent_to(valself, cls)
             or cls == self.vm.convert.type_type):
         # Since type(type) == type, the type_type check prevents an infinite loop.
         meta = None
     else:
         # We treat a class as an instance of its metaclass, but only if we are
         # looking for a class rather than an instance attribute. (So, for
         # instance, if we're analyzing int.mro(), we want to retrieve the mro
         # method on the type class, but for (3).mro(), we want to report that the
         # method does not exist.)
         meta = cls.get_class()
     return self._get_attribute(node, cls, meta, name, valself)
Beispiel #3
0
 def _lookup_from_mro(self, node, cls, name, valself, skip):
     """Find an identifier in the MRO of the class."""
     if isinstance(cls, (abstract.Unknown, abstract.Unsolvable)):
         # We don't know the object's MRO, so it's possible that one of its
         # bases has the attribute.
         return self.vm.new_unsolvable(node)
     ret = self.vm.program.NewVariable()
     add_origins = [valself] if valself else []
     for base in cls.mro:
         # Potentially skip start of MRO, for super()
         if base is skip:
             continue
         # When a special attribute is defined on a class buried in the MRO,
         # get_attribute (which calls get_special_attribute) is never called on
         # that class, so we have to call get_special_attribute here as well.
         var = base.get_special_attribute(node, name, valself)
         if var is None:
             node, var = self._get_attribute_flat(node, base, name)
         if var is None or not var.bindings:
             continue
         for varval in var.bindings:
             value = varval.data
             if valself:
                 # Check if we got a PyTDFunction from an InterpreterClass. If so,
                 # then we must have aliased an imported function inside a class, so
                 # we shouldn't bind the function to the class.
                 if (not isinstance(value, abstract.PyTDFunction) or
                         not isinstance(base, abstract.InterpreterClass)):
                     # See AtomicAbstractValue.property_get for an explanation of the
                     # parameters we're passing here.
                     value = value.property_get(
                         valself.AssignToNewVariable(node),
                         abstract_utils.equivalent_to(valself, cls))
                 if isinstance(value, abstract.Property):
                     node, value = value.call(node, None, None)
                     final_values = value.data
                 else:
                     final_values = [value]
             else:
                 final_values = [value]
             for final_value in final_values:
                 ret.AddBinding(final_value, [varval] + add_origins, node)
         break  # we found a class which has this attribute
     return ret