は、email
パッケージと日付ヘッダーに無効な時間にメールをロードした後、date
ヘッダにアクセスしようとすると、ValueError
例外をスロースロー:メールは、Python 3.5または3.6を使用して例外
>>> import email
>>> from email import policy
>>> m = email.message_from_binary_file(open('bad_date.txt', 'rb'), policy=policy.default)
>>> m['date']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/email/message.py", line 391, in __getitem__
return self.get(name)
File "/usr/lib/python3.6/email/message.py", line 471, in get
return self.policy.header_fetch_parse(k, v)
File "/usr/lib/python3.6/email/policy.py", line 162, in header_fetch_parse
return self.header_factory(name, value)
File "/usr/lib/python3.6/email/headerregistry.py", line 586, in __call__
return self[name](name, value)
File "/usr/lib/python3.6/email/headerregistry.py", line 197, in __new__
cls.parse(value, kwds)
File "/usr/lib/python3.6/email/headerregistry.py", line 303, in parse
value = utils.parsedate_to_datetime(value)
File "/usr/lib/python3.6/email/utils.py", line 214, in parsedate_to_datetime
tzinfo=datetime.timezone(datetime.timedelta(seconds=tz)))
ValueError: hour must be in 0..23
これは、電子メールからヘッダです:
Date: Tue, 06 Jun 2017 27:39:33 +0600
(私はスパムメールを分析していて、誰かの迷惑メール送信プログラムは、私はまた、負の時間を見てきましたタイムゾーンの変換の仕組みを理解していないようです。 ..)
email
パッケージは、電子メールの解析中に発生した問題に対処するように設計されています(この場合、例外をスローすると間違った結果になることがあります)。
この状況に対処するdefault
ポリシーの一部であるデフォルトのheader_factory
を更新しようとする可能性がありますが、parsedate_to_datetime
がこのように動作するPythonのバグのようです。 (どうやらこの動作はon purposeです。)
UPDATE:
from email import policy
from email import errors
from email import _header_value_parser as parser
from email.headerregistry import HeaderRegistry, DateHeader
class DateHeaderRobust(DateHeader):
"""
Copied and updated from email/headerregistry.py to handle
ValueError returned by parsedate_to_datetime when a date header
has an invalid hour value (outside 0..23)
"""
@classmethod
def parse(cls, value, kwds):
try:
super().parse(value, kwds)
except ValueError:
kwds['defects'].append(
errors.InvalidHeaderDefect('Invalid value in date'))
kwds['datetime'] = None
kwds['decoded'] = value
kwds['parse_tree'] = parser.TokenList()
class UniqueDateHeader(DateHeaderRobust):
max_count = 1
header_factory = HeaderRegistry()
header_factory.map_to_type('date', UniqueDateHeader)
email_policy = policy.default.clone(header_factory=header_factory)
そしてメッセージを読む:私はPython bug
?その日付が 'NONE'?それとも何か他のものに設定されている? –
はい、私はparsedate_to_datetimeは' NONE'を返すことを期待したい、WHIは、 chはUniqueDateHeaderオブジェクトに 'datetime'属性として格納されます。 – TimB
また、 'DateHeader'クラスは、欠陥を登録するためにわずかに変更する必要があります。その後、' none'となるので、parsedate_to_datetimeから返された値をさらに処理しようとしません。 – TimB