'Return a hit for a getattr on the given element.
Returns (<hit>, <num-tokens-consumed>) or raises an CodeIntelError.
Typically this just does a getattr of tokens[0], but handling
some multi-level imports can result in multiple tokens being
consumed.'

def _hit_from_getattr(self, tokens, elem, scoperef):

    first_token = tokens[0]
    self.log("resolve    getattr    '%s'    on    %r    in    %r:", first_token, elem, scoperef)
    if (elem.tag == 'variable'):
        (elem, scoperef) = self._hit_from_variable_type_inference(elem, scoperef)
    assert (elem.tag == 'scope')
    ilk = elem.get('ilk')
    if (ilk == 'function'):
        pass
    elif (ilk == 'class'):
        attr = elem.names.get(first_token)
        if (attr is not None):
            self.log('attr    is    %r    in    %r', attr, elem)
            scoperef = (scoperef[0], (scoperef[1] + [elem.get('name')]))
            return ((attr, scoperef), 1)
        if (first_token == '__class__'):
            self.log('attr    is    class    %r', elem)
            return ((elem, scoperef), 1)
        self.debug('look    for    %r    from    imports    in    %r', tokens, elem)
        (hit, nconsumed) = self._hit_from_elem_imports(tokens, elem)
        if (hit is not None):
            return (hit, nconsumed)
        for classref in elem.get('classrefs', '').split():
            try:
                self.log("is    '%s'    from    base    class:    %r?", first_token, classref)
                (base_elem, base_scoperef) = self._hit_from_type_inference(classref, scoperef)
                return self._hit_from_getattr(tokens, base_elem, base_scoperef)
            except CodeIntelError as ex:
                self.log("could    not    resolve    classref    '%s'    on    scoperef    %r", classref, scoperef)
    elif (ilk == 'blob'):
        attr = elem.names.get(first_token)
        if (attr is not None):
            self.log('attr    is    %r    in    %r', attr, elem)
            return ((attr, scoperef), 1)
        (hit, nconsumed) = self._hit_from_elem_imports(tokens, elem)
        if (hit is not None):
            return (hit, nconsumed)
    else:
        raise NotImplementedError(('unexpected    scope    ilk:    %r' % ilk))
    raise CodeIntelError(("could    not    resolve    '%s'    getattr    on    %r    in    %r" % (first_token, elem, scoperef)))
