- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在运行lint,如下所示:
$ python -m pylint.lint m2test.py
import M2Crypto
def f():
M2Crypto.RSA.new_pub_key("").as_pem(cipher=None).split("\n")
Exception AttributeError: '_shutdown' in <module 'threading' from '/usr/lib/python2.7/site-packages/M2Crypto-0.21.1-py2.7-linux-x86_64.egg/M2Crypto/threading.pyc'> ignored
最佳答案
您所看到的异常是由astng
程序包(可能是“抽象语法树,下一代”?)中的错误引起的,该程序包是pylint
所依赖的工具包,由同一人编写。我应该顺便指出,我总是鼓励人们在可能的情况下使用pyflakes
而不是pylint
,因为它快速,简单,快速且可预测,而pylint
试图做一些深层的魔术,但并非如此只是速度很慢,但这可以使它陷入这种麻烦。 :)
这是PyPI上的两个软件包:
http://pypi.python.org/pypi/pylint
http://pypi.python.org/pypi/astng
并请注意,这个问题一定是pylint
中的错误,而不是您的代码中的错误,因为pylint
不会运行您的代码以生成其报告-想象一下,如果这样做会造成严重破坏(因为被删除的代码可能会删除文件等)!由于您的代码无法运行,因此无需采取任何谨慎措施,例如使用线程init()
或cleanup()
函数保护您的调用,就可能避免了该错误-除非出于其他原因而发生了代码片段以改变我们的行为,即将调查。
因此,根据您的实际例外情况。
我以前从未真正听说过_shutdown
!快速搜索Python标准库会在threading.py
中显示其定义,但无法从任何地方调用该函数。仅通过搜索Python C源代码,我才发现在解释器关闭期间pythonrun.c
中的位置实际上是在调用什么:
static void
wait_for_thread_shutdown(void)
{
...
PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
"threading");
if (threading == NULL) {
/* threading not imported */
PyErr_Clear();
return;
}
result = PyObject_CallMethod(threading, "_shutdown", "");
if (result == NULL) {
PyErr_WriteUnraisable(threading);
}
...
}
threading
标准库模块所需的某种清理函数,并且他们对Python解释器本身进行了特殊区分,以确保其被调用。
threading
模块在程序运行期间从未导入的情况。但是,如果确实导入了
threading
,并且在关闭时仍然存在,则解释器会在内部查找
_shutdown
函数,甚至可以打印错误消息-然后返回非零退出状态,这是原因您的问题-如果无法解决。
threading
模块存在但为什么
_shutdown
在检查程序并且Python退出时却没有
pylint
方法的原因。需要某种仪器。我们可以打印出
pylint
退出时模块的外观吗?我们可以!
pylint/lint.py
模块的最后几行通过实例化已定义的
Run
类来运行其“主程序”:
if __name__ == '__main__':
Run(sys.argv[1:])
lint.py
(在Python Virual Environment中安装每个小项目的宏伟的事情之一就是,我可以跳入并编辑第三方代码以进行快速实验),并添加了以下
print
语句在
Run
类的
__init__()
方法的底部:
sys.path.pop(0)
print "*****", sys.modules['threading'].__file__ # added by me!
if exit:
sys.exit(self.linter.msg_status)
python -m pylint.lint m2test.py
__file__
模块的
threading
字符串:
***** /home/brandon/venv/lib/python2.7/site-packages/M2Crypto/threading.pyc
M2Crypto/threading.py
模块,在所有正常情况下,该模块仅应称为
M2Crypto.threading
,因此位于
sys.modules
词典中,其名称为:
sys.modules['M2Crypto.threading']
threading
模块加载,从而掩盖了标准库中的官方
threading
模块。因此,Python退出逻辑非常正确地抱怨标准库
_shutdown()
函数丢失。
sys.path
中明确列出的路径中,而不能出现在它们下面的子目录中。这就引出了一个新的问题:在
pylint
运行期间,是否有任何迹象表明
…/M2Crypto/
目录本身被放置在
sys.path
上,好像它包含顶级模块一样?让我们来看看!
M2Crypto
的目录出现在
sys.path
中的那一刻。这确实会使速度变慢,但让我们在pylint的
__init__.py
中添加跟踪函数-因为这是您在运行
-m pylint.lint
时导入的第一个模块-它将为执行的每一行代码写一个输出文件,告诉我们,其中
sys.path
是否包含任何错误值:
def install_tracer():
import sys
output = open('mytracer.out', 'w')
def mytracer(frame, event, arg):
broken = any(p.endswith('M2Crypto') for p in sys.path)
output.write('{} {}:{} {}\n'.format(
broken, frame.f_code.co_filename, frame.f_lineno, event))
return mytracer
sys.settrace(mytracer)
install_tracer()
del install_tracer
pylint
继续加载之前,仔细删除该名称以进行清理。跟踪功能本身需要的所有资源(即
sys
模块和
output
打开文件)在
install_tracer()
闭包中可用,因此从外部看,
pylint
与总是。以防万一有人尝试自省,就像
pylint
一样!
mytracer.out
,每行看起来像这样:
False /home/brandon/venv/lib/python2.7/posixpath.py:118 call
False
表示
sys.path
看起来很干净,文件名和行号是正在执行的代码行,
call
表示解释器处于执行的哪个阶段。
sys.path
是否会中毒?让我们看一下每行的第一个
True
或
False
,并查看从每个值开始的连续几行:
$ awk '{print$1}' mytracer.out | uniq -c
607997 False
3173 True
4558 False
33217 True
4304 False
41699 True
2953 False
110503 True
52575 False
True
,这意味着解释器在路径上应以
…/M2Crypto/
或路径名称的某种变体(其中带有
M2Crypto
)运行。不仅包含
…/M2Crypto
的目录应该位于路径上。在文件中寻找第一个从
False
到
True
的过渡,我看到了:
False /home/brandon/venv/lib/python2.7/site-packages/logilab/astng/builder.py:132 line
False /home/brandon/venv/lib/python2.7/posixpath.py:118 call
...
False /home/brandon/venv/lib/python2.7/posixpath.py:124 line
False /home/brandon/venv/lib/python2.7/posixpath.py:124 return
True /home/brandon/venv/lib/python2.7/site-packages/logilab/astng/builder.py:133 line
builder.py
文件中的第132和133行揭示了我们的罪魁祸首:
130 # build astng representation
131 try:
132 sys.path.insert(0, dirname(path)) # XXX (syt) iirk
133 node = self.string_build(data, modname, path)
134 finally:
135 sys.path.pop(0)
XXX (syt) iirk
是该程序员奇怪的母语中的短语“这个模块的父目录放在
sys.path
上,这样,每次有人强迫
pylint
用< cc>子模块。”显然,它是一种非常紧凑的母语。 :)
pylint
实际导入的
threading
(我将留给读者的练习),您会看到它发生在
sys.modules
上,它是由其他标准库模块在该分析又试图无害地导入
threading
。
SocketServer
是危险的魔法。
threading
,则它会尝试在磁盘上查找
pylint
,对其进行解析并预测要从其名称空间加载有效名称还是无效名称。
import foo
的返回值上调用
foo.py
,所以
.split()
会尝试自省
RSA.as_pem()
方法,该方法又使用
pylint
模块,该模块又进行调用导致
as_pem()
导入
M2Crypto.BIO
。
pylint
的一部分,
threading
会在
foo.py
上抛出包含
pylint
的目录,即使该目录位于软件包中,因此也为该目录中的模块提供了对标准库模块的影子化的特权。在分析过程中使用相同的名称。
foo.py
库位于
sys.path
所属的地方会很不高兴,因为它想运行
M2Crypto.threading
的
threading
方法。
_shutdown()
的
threading
/
pylint
同事。告诉他们我发给你了。
astng
之后继续使用它,那么在这种情况下似乎有两种解决方案:要么不检查调用
logilab.org
的代码,要么在
pylint
期间导入
M2Crypto
导入过程(例如,将
threading
粘贴到
pylint
中),以使模块有机会在
import threading
兴奋之前尝试抓住
pylint/__init__.py
插槽,并尝试让
sys.modules['threading']
代替插槽。
pylint
的作者说得最好:XXX(syt)iirk。确实。
关于python - 插入使用M2Crypto的代码时,_shutdown AttributeError(忽略),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7302769/
我正在运行lint,如下所示: $ python -m pylint.lint m2test.py 使用此代码: import M2Crypto def f(): M2Crypto.RSA.n
我是一名优秀的程序员,十分优秀!