Vim的omnicompletion在Python中使用“from”导入失败

时间:2010-07-09 13:40:58

标签: python vim omnicomplete import

当存在“从”导入而不是正常导入时,Python的Omnicompletion似乎失败了。 例如,如果我有这两个文件:

Test.py:

class Test:
    def method(self):
        pass

main.py:

from Test import Test

class Test2:
    def __init__(self):
       self.x = Test()

如果我尝试为self.x激活omnicompletion ...它会显示“Pattern not found”。 但是,如果我将import语句更改为:

import Test

和self.x声明:

self.x = Test.Test()

然后我可以按预期使用omnicompletion(例如,它建议使用“方法”)。

我正在使用Vim 7.2.245和Python代码完成的默认插件(pythoncomplete)。 我应该设置一些变量吗?或者预期会出现这种情况吗?

更新

根据Jared的回答,我偶然发现了一些事情:

Omnicompletion对此不起作用:

from StringIO import StringIO

class Test:
    def __init__(self):
        self.x = StringIO()
        self.x.<C-x><C-o>

s = Test()

但是就此而言:

from StringIO import StringIO

class Test:
    def __init__(self):
        self.x = StringIO()
        self.x.<C-x><C-o>

s = Test()
s.x = StringIO()

唯一的区别是x的重新声明(实际上,如果我删除__init__中的声明,它也有效。)

我再次测试了我的例子,我认为问题不在于“from”导入,而是在另一个类中使用导入的类。 如果我将文件main.py更改为:

from Test import Test

class Test2:
    def __init__(self):
       self.x = Test()
       self.x.<C-x><C-o>

y = Test()
y.<C-x><C-o>

使用omnicompletion的第一次尝试失败,但第二次正常工作。 所以,看起来像插件中的一个错误:)

1 个答案:

答案 0 :(得分:2)

更新:哦,所以我检查了你的例子,我完成了

x = Test()
x.<C-x><C-o>

但不是

o = object()
o.x = Test()
o.x.<C-x><C-o>

......我要做一些挖掘

更新2: Strangelove博士的复仇

和...这就是它变得奇怪的地方。

from StringIO import StringIO
class M:
    pass
s = M()
s.x = StringIO()
s.x.<C-x><C-o>

完成。但是这个

from StringIO import StringIO
class M: pass
s = M()
s.x = StringIO()
s.x.<C-x><C-o>

你有没有发现差异? 没有语法上的东西 - 只是一个小空白

然而它完成了。所以在那里肯定存在一个解析错误(为什么他们不只是使用ast模块,我不知道......)

[更新结束]

乍一看,我无法重现你的问题;这是我的测试文件:

from os import path
path.<C-x><C-o>

我完成了。现在,我知道这不是你的情况,但它表明pythoncomplete知道'from'。

现在更深入的例子:

from StringIO import StringIO
s = StringIO()
s.<C-x><C-o>

和...完成!您是否可以尝试使用查看它是否适用于内置模块?如果是这种情况,您应该查看路径......

如果它仍然不起作用,并且你需要进行一些挖掘,请查看pythoncomplete.vim的第555行[在我的ubuntu机器上的/usr/share/vim/vim72/autoload/pythoncomplete.vim]:

            elif token == 'from':                                    
                mod, token = self._parsedotname()                    
                if not mod or token != "import":                     
                    print "from: syntax error..."                    
                    continue                                         
                names = self._parseimportlist()                      
                for name, alias in names:                            
                    loc = "from %s import %s" % (mod,name)           
                    if len(alias) > 0: loc += " as %s" % alias       
                    self.scope.local(loc)                            
                freshscope = False                                   

如您所见,这是处理from语句的地方。

干杯