如何恢复一个破碎的巨蟒“的cPickle”倾倒?

我使用rss2email用于将数量的RSS馈送到邮件,方便食用。 也就是说, 用它,因为它在一个可怕的方式今天爆发:在每次运行时,它只是给了我这个回溯:

Traceback (most recent call last): File "/usr/share/rss2email/rss2email.py", line 740, in <module> elif action == "list": list() File "/usr/share/rss2email/rss2email.py", line 681, in list feeds, feedfileObject = load(lock=0) File "/usr/share/rss2email/rss2email.py", line 422, in load feeds = pickle.load(feedfileObject) TypeError: ("'str' object is not callable", 'sxOYAAuyzSx0WqN3BVPjE+6pgPU', ((2009, 3, 19, 1, 19, 31, 3, 78, 0), {}))

唯一有用的事实,我已经能够从这个回溯建设是该文件~/.rss2email/feeds.dat其中rss2email保持其所有的配置和运行状态,以某种方式打破。 显然rss2email读取其状态,并使用转储回来cPickle在每次运行。

我甚至发现包含该行'sxOYAAuyzSx0WqN3BVPjE+6pgPU'字符串中的巨人(> 12MB)上述feeds.dat文件。 为了我的未经训练的眼睛,转储不会出现被截断或损坏。

我可以为了重建文件尝试什么样的方法?

Python的版本是2.5.4在Debian /不稳定的系统。

编辑

彼得·吉布森和JF塞巴斯蒂安建议直接从泡菜文件加载,我曾尝试过。 很显然,一个Feed了在定义的类rss2email.py是必要的,所以这里是我的脚本:

#!/usr/bin/python import sys # import pickle import cPickle as pickle sys.path.insert(0,"/usr/share/rss2email") from rss2email import Feed feedfile = open("feeds.dat", 'rb') feeds = pickle.load(feedfile)

在“普通”泡菜变种产生以下回溯:

Traceback (most recent call last): File "./r2e-rescue.py", line 8, in <module> feeds = pickle.load(feedfile) File "/usr/lib/python2.5/pickle.py", line 1370, in load return Unpickler(file).load() File "/usr/lib/python2.5/pickle.py", line 858, in load dispatch[key](self) File "/usr/lib/python2.5/pickle.py", line 1133, in load_reduce value = func(*args) TypeError: 'str' object is not callable

cPickle变种基本上产生同样的事情,呼吁r2e本身:

Traceback (most recent call last): File "./r2e-rescue.py", line 10, in <module> feeds = pickle.load(feedfile) TypeError: ("'str' object is not callable", 'sxOYAAuyzSx0WqN3BVPjE+6pgPU', ((2009, 3, 19, 1, 19, 31, 3, 78, 0), {}))

编辑2

继JF Sebastian的周围放“的printf调试”成建议Feed.__setstate__到我的测试脚本,这些都是过去的几行之前的Python捞出。

u'http:/com/news.ars/post/20080924-everyone-declares-victory-in-smutfree-wireless-broadband-test.html': u'http:/com/news.ars/post/20080924-everyone-declares-victory-in-smutfree-wireless-broadband-test.html'}, 'to': None, 'url': 'http://arstechnica.com/'} Traceback (most recent call last): File "./r2e-rescue.py", line 23, in ? feeds = pickle.load(feedfile) TypeError: ("'str' object is not callable", 'sxOYAAuyzSx0WqN3BVPjE+6pgPU', ((2009, 3, 19, 1, 19, 31, 3, 78, 0), {}))

同样的事情发生在使用python 2.4.4-2在Debian /蚀刻框。

--------------解决方案-------------

如何我解决我的问题

的Perl移植pickle.py

继JF塞巴斯蒂安的评论如何简单的pickle格式,我出去的端口部分pickle.py给Perl。 一对夫妇的快速正则表达式将是一个更快的方法来访问我的数据,但我认为,黑客的价值,并有机会更多地了解Python的将是值得的。 另外,我还是觉得更舒适使用(和调试代码)的Perl比Python。

大多数移植工作的(简单类型,元组,列表,字典)又非常简单。 Perl的和Python的不同类和对象的概念一直是唯一的问题,到目前为止,其中多一点不是简单的成语翻译需要。 其结果是一个名为模块Pickle::Parse这后一点抛光将在CPAN上公布。

所谓模块Python::Serialise::Pickle存在于CPAN,但我发现它的解析能力欠缺:它喷出调试输出所有的地方,似乎不支持类/对象。

解析,转换数据,在流中检测实际的错误

基于Pickle::Parse ,我试图解析feeds.dat文件。 固定微不足道的错误在我的分析代码的几个迭代后,我得到的是惊人相似的错误消息pickle.py原始对象不可调用的错误信息:

Can't use string ("sxOYAAuyzSx0WqN3BVPjE+6pgPU") as a subroutine
ref while "strict refs" in use at lib/Pickle/Parse.pm line 489,
<STDIN> line 187102.

哈! 现在,我们正处在一个点,它是很有可能的实际数据流被打破。 另外,我们得到一个想法在那里被打破。

原来,按以下顺序的第一行是错误的:

g7724
((I2009
I3
I19
I1
I19
I31
I3
I78
I0
t(dtRp62457

在“备忘录”的位置7724指出,该字符串"sxOYAAuyzSx0WqN3BVPjE+6pgPU" 从类似的记录前面的流中,很明显,一个time.struct_time是需要对象,而不是。 所有后来的记录共享这个错误的指针。 用一个简单的查找/替换操作,这是微不足道的解决这个问题。

我觉得讽刺的是,我找到了错误的根源是偶然通过Perl的功能,告诉用户它的位置输入数据流中时,它死了。

结论

  1. 我会搬离rss2email只要我有时间来自动改变其腌制的配置/状态乱七八糟的另一种工具的格式。
  2. pickle.py需要告诉有关数据流(而不是在自己的代码中poision),其中出问题的位置,用户更有意义的错误消息。
  3. 移植部位pickle.py给Perl很有趣并且,在最后,有收获。

你有没有尝试过手动加载同时使用的cPickle和泡菜的feeds.dat文件? 如果输出的不同,可能暗示该错误。

喜欢的东西(你的主目录):

import cPickle, pickle
f = open('.rss2email/feeds.dat', 'r')
obj1 = cPickle.load(f)
obj2 = pickle.load(f)

(您可能需要以二进制模式“RB”,打开如果rss2email不以ASCII咸菜)。

皮特

编辑:事实上,cPickle时和泡菜给予相同的错误表明feeds.dat文件是问题所在。 可能是因为在Ubuntu臭虫JF塞巴斯蒂安建议在rss2email版本之间的Feed类的变化链接到。

听起来像的cPickle的内部越来越纠缠不清。 这个线程(http://bytes.com/groups/python/565085-cpickle-problems)看起来像它可能有一个线索..

  1. 'sxOYAAuyzSx0WqN3BVPjE+6pgPU'是最有可能无关的泡菜的问题
  2. 职位(以确定哪些类定义不能被称为属性(一个通向类型错误)的错误追踪:

    python -c "import pickle; pickle.load(open('feeds.dat'))"

编辑:

以下内容添加到您的代码并运行(stderr重定向到文件,然后使用'tail -2'它来打印最后两行):

from pprint import pprint
def setstate(self, dict_):
pprint(dict_, stream=sys.stderr, depth=None)
self.__dict__.update(dict_)
Feed.__setstate__ = setstate

如果上面没有产生一个有趣的输出,然后使用常规疑难解答策略:

确认'feeds.dat'的问题:

  • 备份~/.rss2email目录
  • 安装rss2email到的virtualenv / PIP沙箱(或使用zc.buildout)来隔离环境(请确保您使用feedparser.py从树干)。
  • 添加夫妇饲料,添加饲料直到'feeds.dat'大小大于电流。 运行一些测试。
  • 尝试老'feeds.dat“
  • 尝试在现有rss2email安装新的“feeds.dat”

见R2E捞出在Ubuntu类型错误的bug。

分类:蟒蛇 时间:2012-04-20 人气:0
本文关键词: 蟒蛇,RSS,泡菜
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.433 (s). 10 q(s)