'Python trigger types:
python-complete-object-members
python-calltip-call-signature
python-complete-pythondoc-tags
complete-available-imports
complete-module-members
Not yet implemented:
complete-available-classes
calltip-base-signature'

def trg_from_pos(self, pos, implicit=True):

    DEBUG = False
    if DEBUG:
        print ('\n-----    Python    trg_from_pos(pos=%r,    implicit=%r)    -----' % (pos, implicit))
    if (pos == 0):
        return None
    accessor = self.accessor
    last_pos = (pos - 1)
    last_char = accessor.char_at_pos(last_pos)
    if DEBUG:
        print ('        last_pos:    %s' % last_pos)
        print ('        last_char:    %r' % last_char)
    style = accessor.style_at_pos(last_pos)
    if DEBUG:
        style_names = self.style_names_from_style_num(style)
        print ('        style:    %s    (%s)' % (style, ',    '.join(style_names)))
    if (last_char == '@'):
        if (style in self.comment_styles()):
            WHITESPACE = tuple('     DCTB ')
            SENTINEL = 20
            i = (last_pos - 1)
            while (i >= max(0, (last_pos - SENTINEL))):
                ch = accessor.char_at_pos(i)
                if (ch == '#'):
                    return Trigger(self.lang, TRG_FORM_CPLN, 'pythondoc-tags', pos, implicit)
                elif (ch in WHITESPACE):
                    pass
                else:
                    return None
                i -= 1
        return None
    if ((implicit and (style in self.implicit_completion_skip_styles) and (last_char != '_')) or (style in self.completion_skip_styles)):
        if DEBUG:
            print ('trg_from_pos:    no:    completion    is    suppressed    in    style    at    %s:    %s    (%s)' % (last_pos, style, ',    '.join(style_names)))
        return None
    if (last_char == '    '):
        if (((last_pos - 1) < 0) or (accessor.char_at_pos((last_pos - 1)) not in 'etm,')):
            return None
        working_text = accessor.text_range(max(0, (last_pos - 200)), last_pos)
        line = self._last_logical_line(working_text).strip()
        if (not line):
            return None
        ch = line[(-1)]
        line = line.replace(' DCTB ', '    ')
        if ((line == 'from') or (line == 'import')):
            return Trigger(self.lang, TRG_FORM_CPLN, 'available-imports', pos, implicit, imp_prefix=())
        if line.endswith('    import'):
            if line.startswith('from    '):
                imp_prefix = tuple(line[len('from    '):(- len('    import'))].strip().split('.'))
                return Trigger(self.lang, TRG_FORM_CPLN, 'module-members', pos, implicit, imp_prefix=imp_prefix)
        if ((line == 'except') or (line == 'raise') or line.endswith(('    except', '    raise'))):
            return Trigger(self.lang, TRG_FORM_CPLN, 'available-exceptions', pos, implicit)
        if (ch == ','):
            if (line.startswith('from    ') and ('    import    ' in line)):
                imp_prefix = tuple(line[len('from    '):line.index('    import')].strip().split('.'))
                return Trigger(self.lang, TRG_FORM_CPLN, 'module-members', pos, implicit, imp_prefix=imp_prefix)
    elif (last_char == '.'):
        working_text = accessor.text_range(max(0, (last_pos - 200)), last_pos)
        line = self._last_logical_line(working_text).strip()
        if line:
            ch = line[(-1)]
            if (isident(ch) or isdigit(ch) or (ch in '.)')):
                line = line.replace(' DCTB ', '    ')
                m = _dotted_from_rx.match(line)
                if m:
                    dots = len(m.group(1).strip())
                    imp_prefix = tuple(('' for i in xrange((dots + 2))))
                    return Trigger(self.lang, TRG_FORM_CPLN, 'available-imports', pos, implicit, imp_prefix=imp_prefix)
                elif line.startswith('from    '):
                    if ('    import    ' in line):
                        return None
                    imp_prefix = tuple(line[len('from    '):].strip().split('.'))
                    return Trigger(self.lang, TRG_FORM_CPLN, 'available-imports', pos, implicit, imp_prefix=imp_prefix)
                elif line.startswith('import    '):
                    imp_prefix = tuple(line[len('import    '):].strip().split('.'))
                    return Trigger(self.lang, TRG_FORM_CPLN, 'available-imports', pos, implicit, imp_prefix=imp_prefix)
                else:
                    return Trigger(self.lang, TRG_FORM_CPLN, 'object-members', pos, implicit)
            elif (ch in '"\''):
                return Trigger(self.lang, TRG_FORM_CPLN, 'literal-members', pos, implicit, citdl_expr='str')
        else:
            ch = None
        if DEBUG:
            print ("trg_from_pos:    no:    non-ws    char    preceding    '.'    is    not    an    identifier    char    or    ')':    %r" % ch)
        return None
    elif (last_char == '_'):
        if (((last_pos - 1) < 0) or (accessor.char_at_pos((last_pos - 1)) != '_')):
            return None
        beforeChar = None
        beforeStyle = None
        if ((last_pos - 2) >= 0):
            beforeChar = accessor.char_at_pos((last_pos - 2))
            beforeStyle = accessor.style_at_pos((last_pos - 2))
        if DEBUG:
            print ('trg_from_pos::    checking    magic    symbol,    beforeChar:    %r' % beforeChar)
        if (beforeChar and (beforeChar in '"\'') and (beforeStyle in self.string_styles())):
            if DEBUG:
                print 'trg_from_pos::    magic-symbols    -    string'
            return Trigger(self.lang, TRG_FORM_CPLN, 'magic-symbols', (last_pos - 1), implicit, symbolstype='string')
        elif ((beforeChar == '.') and (beforeStyle != style)):
            return None
        if (beforeStyle == style):
            return None
        text = accessor.text_range(max(0, (last_pos - 20)), (last_pos - 1)).strip()
        if (beforeChar and (beforeChar in '     DCTB ')):
            if text.endswith('def'):
                posttext = accessor.text_range(pos, min(accessor.length, (pos + 20))).replace('    ', '')
                if DEBUG:
                    print 'trg_from_pos::    magic-symbols    -    def'
                return Trigger(self.lang, TRG_FORM_CPLN, 'magic-symbols', (last_pos - 1), implicit, symbolstype='def', posttext=posttext)
        if DEBUG:
            print 'trg_from_pos::    magic-symbols    -    global'
        return Trigger(self.lang, TRG_FORM_CPLN, 'magic-symbols', (last_pos - 1), implicit, symbolstype='global', text=text)
    elif (last_char == '('):
        working_text = accessor.text_range(max(0, (last_pos - 200)), last_pos)
        line = self._last_logical_line(working_text).rstrip()
        if line:
            ch = line[(-1)]
            if (isident(ch) or isdigit(ch)):
                line = line.replace(' DCTB ', '    ')
                lstripped = line.lstrip()
                if lstripped.startswith('def'):
                    if DEBUG:
                        print 'trg_from_pos:    no:    point    is    function    declaration'
                elif (lstripped.startswith('class') and ('(' not in lstripped)):
                    if DEBUG:
                        print 'trg_from_pos:    no:    point    is    class    declaration'
                elif (lstripped.startswith('from    ') and ('    import' in lstripped)):
                    imp_prefix = tuple(lstripped[len('from    '):lstripped.index('    import')].split('.'))
                    if DEBUG:
                        print 'trg_from_pos:    from    FOO    import    ('
                    return Trigger(self.lang, TRG_FORM_CPLN, 'module-members', pos, implicit, imp_prefix=imp_prefix)
                else:
                    return Trigger(self.lang, TRG_FORM_CALLTIP, 'call-signature', pos, implicit)
            elif DEBUG:
                print ("trg_from_pos:    no:    non-ws    char    preceding    '('    is    not    an    identifier    char:    %r" % ch)
        elif DEBUG:
            print "trg_from_pos:    no:    no    chars    preceding    '('"
        return None
    elif (last_char == ','):
        working_text = accessor.text_range(max(0, (last_pos - 200)), last_pos)
        line = self._last_logical_line(working_text)
        if line:
            last_bracket = line.rfind('(')
            if (last_bracket >= 0):
                pos = (pos - (len(line) - last_bracket))
                return Trigger(self.lang, TRG_FORM_CALLTIP, 'call-signature', pos, implicit)
            return None
        else:
            return None
    elif ((pos >= 2) and (style in (self.identifier_style, self.keyword_style))):
        if DEBUG:
            if (style == self.identifier_style):
                print 'Identifier    style'
            else:
                print 'Identifier    keyword    style'
        if ((accessor.style_at_pos((last_pos - 1)) != style) or ((pos > 2) and (accessor.style_at_pos((last_pos - 2)) == style))):
            if DEBUG:
                print 'Not    a    block    of    two    ident/word    chars'
            return None
        if ((pos > 2) and (accessor.char_at_pos((last_pos - 2)) == '.')):
            if DEBUG:
                print "        preceeded    by    '.'    operator    -    not    a    trigger"
            return None
        start = accessor.line_start_pos_from_pos(pos)
        preceeding_text = accessor.text_range(start, (last_pos - 2)).strip()
        if preceeding_text:
            first_word = preceeding_text.split('    ')[0]
            if (first_word in ('class', 'def', 'import', 'from', 'except')):
                if DEBUG:
                    print ('        no    trigger,    as    starts    with    %r' % (first_word,))
                return None
        citdl_expr = accessor.text_range((last_pos - 1), (last_pos + 1))
        if DEBUG:
            print ('        triggered    2    char    symbol    trigger:    %r' % (citdl_expr,))
        return Trigger(self.lang, TRG_FORM_CPLN, 'local-symbols', (last_pos - 1), implicit, citdl_expr=citdl_expr, preceeding_text=preceeding_text)
