Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
06ed218e
Kaydet (Commit)
06ed218e
authored
Eyl 09, 2016
tarafından
R David Murray
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
#20476: add a message_factory policy attribute to email.
üst
37df068e
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
128 additions
and
66 deletions
+128
-66
email.parser.rst
Doc/library/email.parser.rst
+11
-9
email.policy.rst
Doc/library/email.policy.rst
+11
-0
3.6.rst
Doc/whatsnew/3.6.rst
+7
-0
_policybase.py
Lib/email/_policybase.py
+4
-0
feedparser.py
Lib/email/feedparser.py
+1
-8
message.py
Lib/email/message.py
+5
-3
policy.py
Lib/email/policy.py
+2
-0
test_parser.py
Lib/test/test_email/test_parser.py
+62
-29
test_policy.py
Lib/test/test_email/test_policy.py
+25
-17
No files found.
Doc/library/email.parser.rst
Dosyayı görüntüle @
06ed218e
...
@@ -73,8 +73,9 @@ Here is the API for the :class:`BytesFeedParser`:
...
@@ -73,8 +73,9 @@ Here is the API for the :class:`BytesFeedParser`:
.. class:: BytesFeedParser(_factory=None, *, policy=policy.compat32)
.. class:: BytesFeedParser(_factory=None, *, policy=policy.compat32)
Create a :class:`BytesFeedParser` instance. Optional *_factory* is a
Create a :class:`BytesFeedParser` instance. Optional *_factory* is a
no-argument callable; if not specified determine the default based on the
no-argument callable; if not specified use the
*policy*. Call *_factory* whenever a new message object is needed.
:attr:`~email.policy.Policy.message_factory` from the *policy*. Call
*_factory* whenever a new message object is needed.
If *policy* is specified use the rules it specifies to update the
If *policy* is specified use the rules it specifies to update the
representation of the message. If *policy* is not set, use the
representation of the message. If *policy* is not set, use the
...
@@ -91,6 +92,7 @@ Here is the API for the :class:`BytesFeedParser`:
...
@@ -91,6 +92,7 @@ Here is the API for the :class:`BytesFeedParser`:
.. versionadded:: 3.2
.. versionadded:: 3.2
.. versionchanged:: 3.3 Added the *policy* keyword.
.. versionchanged:: 3.3 Added the *policy* keyword.
.. versionchanged:: 3.6 _factory defaults to the policy ``message_factory``.
.. method:: feed(data)
.. method:: feed(data)
...
@@ -146,6 +148,7 @@ message body, instead setting the payload to the raw body.
...
@@ -146,6 +148,7 @@ message body, instead setting the payload to the raw body.
.. versionchanged:: 3.3
.. versionchanged:: 3.3
Removed the *strict* argument that was deprecated in 2.4. Added the
Removed the *strict* argument that was deprecated in 2.4. Added the
*policy* keyword.
*policy* keyword.
.. versionchanged:: 3.6 _class defaults to the policy ``message_factory``.
.. method:: parse(fp, headersonly=False)
.. method:: parse(fp, headersonly=False)
...
@@ -194,6 +197,7 @@ message body, instead setting the payload to the raw body.
...
@@ -194,6 +197,7 @@ message body, instead setting the payload to the raw body.
.. versionchanged:: 3.3
.. versionchanged:: 3.3
Removed the *strict* argument. Added the *policy* keyword.
Removed the *strict* argument. Added the *policy* keyword.
.. versionchanged:: 3.6 _class defaults to the policy ``message_factory``.
.. method:: parse(fp, headersonly=False)
.. method:: parse(fp, headersonly=False)
...
@@ -230,8 +234,7 @@ in the top-level :mod:`email` package namespace.
...
@@ -230,8 +234,7 @@ in the top-level :mod:`email` package namespace.
.. currentmodule:: email
.. currentmodule:: email
.. function:: message_from_bytes(s, _class=None, *, \
.. function:: message_from_bytes(s, _class=None, *, policy=policy.compat32)
policy=policy.compat32)
Return a message object structure from a :term:`bytes-like object`. This is
Return a message object structure from a :term:`bytes-like object`. This is
equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
...
@@ -243,7 +246,7 @@ in the top-level :mod:`email` package namespace.
...
@@ -243,7 +246,7 @@ in the top-level :mod:`email` package namespace.
Removed the *strict* argument. Added the *policy* keyword.
Removed the *strict* argument. Added the *policy* keyword.
.. function:: message_from_binary_file(fp, _class=None, *,
\
.. function:: message_from_binary_file(fp, _class=None, *,
policy=policy.compat32)
policy=policy.compat32)
Return a message object structure tree from an open binary :term:`file
Return a message object structure tree from an open binary :term:`file
...
@@ -256,8 +259,7 @@ in the top-level :mod:`email` package namespace.
...
@@ -256,8 +259,7 @@ in the top-level :mod:`email` package namespace.
Removed the *strict* argument. Added the *policy* keyword.
Removed the *strict* argument. Added the *policy* keyword.
.. function:: message_from_string(s, _class=None, *, \
.. function:: message_from_string(s, _class=None, *, policy=policy.compat32)
policy=policy.compat32)
Return a message object structure from a string. This is equivalent to
Return a message object structure from a string. This is equivalent to
``Parser().parsestr(s)``. *_class* and *policy* are interpreted as
``Parser().parsestr(s)``. *_class* and *policy* are interpreted as
...
@@ -267,8 +269,7 @@ in the top-level :mod:`email` package namespace.
...
@@ -267,8 +269,7 @@ in the top-level :mod:`email` package namespace.
Removed the *strict* argument. Added the *policy* keyword.
Removed the *strict* argument. Added the *policy* keyword.
.. function:: message_from_file(fp, _class=None, *, \
.. function:: message_from_file(fp, _class=None, *, policy=policy.compat32)
policy=policy.compat32)
Return a message object structure tree from an open :term:`file object`.
Return a message object structure tree from an open :term:`file object`.
This is equivalent to ``Parser().parse(fp)``. *_class* and *policy* are
This is equivalent to ``Parser().parse(fp)``. *_class* and *policy* are
...
@@ -276,6 +277,7 @@ in the top-level :mod:`email` package namespace.
...
@@ -276,6 +277,7 @@ in the top-level :mod:`email` package namespace.
.. versionchanged:: 3.3
.. versionchanged:: 3.3
Removed the *strict* argument. Added the *policy* keyword.
Removed the *strict* argument. Added the *policy* keyword.
.. versionchanged:: 3.6 _class defaults to the policy ``message_factory``.
Here's an example of how you might use :func:`message_from_bytes` at an
Here's an example of how you might use :func:`message_from_bytes` at an
...
...
Doc/library/email.policy.rst
Dosyayı görüntüle @
06ed218e
...
@@ -221,6 +221,14 @@ added matters. To illustrate::
...
@@ -221,6 +221,14 @@ added matters. To illustrate::
The *mangle_from_* parameter.
The *mangle_from_* parameter.
.. attribute:: message_factory
A factory function for constructing a new empty message object. Used
by the parser when building messages. Defaults to
:class:`~email.message.Message`.
.. versionadded:: 3.6
The following :class:`Policy` method is intended to be called by code using
The following :class:`Policy` method is intended to be called by code using
the email library to create policy instances with custom settings:
the email library to create policy instances with custom settings:
...
@@ -368,6 +376,9 @@ added matters. To illustrate::
...
@@ -368,6 +376,9 @@ added matters. To illustrate::
on the type of the field. The parsing and folding algorithm fully implement
on the type of the field. The parsing and folding algorithm fully implement
:rfc:`2047` and :rfc:`5322`.
:rfc:`2047` and :rfc:`5322`.
The default value for the :attr:`~email.policy.Policy.message_factory`
attribute is :class:`~email.message.EmailMessage`.
In addition to the settable attributes listed above that apply to all
In addition to the settable attributes listed above that apply to all
policies, this policy adds the following additional attributes:
policies, this policy adds the following additional attributes:
...
...
Doc/whatsnew/3.6.rst
Dosyayı görüntüle @
06ed218e
...
@@ -598,6 +598,13 @@ The :mod:`email.mime` classes now all accept an optional *policy* keyword.
...
@@ -598,6 +598,13 @@ The :mod:`email.mime` classes now all accept an optional *policy* keyword.
The :class:`~email.generator.DecodedGenerator` now supports the *policy*
The :class:`~email.generator.DecodedGenerator` now supports the *policy*
keyword.
keyword.
There is a new :mod:`~email.policy` attribute,
:attr:`~email.policy.Policy.message_factory`, that controls what class is used
by default when the parser creates new message objects. For the
:attr:`email.policy.compat32` policy this is :class:`~email.message.Message`,
for the new policies it is :class:`~email.message.EmailMessage`.
(Contributed by R. David Murray in :issue:`20476`.)
encodings
encodings
---------
---------
...
...
Lib/email/_policybase.py
Dosyayı görüntüle @
06ed218e
...
@@ -154,6 +154,8 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
...
@@ -154,6 +154,8 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
them. This is used when the message is being
them. This is used when the message is being
serialized by a generator. Default: True.
serialized by a generator. Default: True.
message_factory -- the class to use to create new message objects.
"""
"""
raise_on_defect
=
False
raise_on_defect
=
False
...
@@ -161,6 +163,8 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
...
@@ -161,6 +163,8 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
cte_type
=
'8bit'
cte_type
=
'8bit'
max_line_length
=
78
max_line_length
=
78
mangle_from_
=
False
mangle_from_
=
False
# XXX To avoid circular imports, this is set in email.message.
message_factory
=
None
def
handle_defect
(
self
,
obj
,
defect
):
def
handle_defect
(
self
,
obj
,
defect
):
"""Based on policy, either raise defect or call register_defect.
"""Based on policy, either raise defect or call register_defect.
...
...
Lib/email/feedparser.py
Dosyayı görüntüle @
06ed218e
...
@@ -24,7 +24,6 @@ __all__ = ['FeedParser', 'BytesFeedParser']
...
@@ -24,7 +24,6 @@ __all__ = ['FeedParser', 'BytesFeedParser']
import
re
import
re
from
email
import
errors
from
email
import
errors
from
email
import
message
from
email._policybase
import
compat32
from
email._policybase
import
compat32
from
collections
import
deque
from
collections
import
deque
from
io
import
StringIO
from
io
import
StringIO
...
@@ -148,13 +147,7 @@ class FeedParser:
...
@@ -148,13 +147,7 @@ class FeedParser:
self
.
policy
=
policy
self
.
policy
=
policy
self
.
_old_style_factory
=
False
self
.
_old_style_factory
=
False
if
_factory
is
None
:
if
_factory
is
None
:
# What this should be:
self
.
_factory
=
policy
.
message_factory
#self._factory = policy.default_message_factory
# but, because we are post 3.4 feature freeze, fix with temp hack:
if
self
.
policy
is
compat32
:
self
.
_factory
=
message
.
Message
else
:
self
.
_factory
=
message
.
EmailMessage
else
:
else
:
self
.
_factory
=
_factory
self
.
_factory
=
_factory
try
:
try
:
...
...
Lib/email/message.py
Dosyayı görüntüle @
06ed218e
...
@@ -4,18 +4,17 @@
...
@@ -4,18 +4,17 @@
"""Basic message object for the email package object model."""
"""Basic message object for the email package object model."""
__all__
=
[
'Message'
]
__all__
=
[
'Message'
,
'EmailMessage'
]
import
re
import
re
import
uu
import
uu
import
quopri
import
quopri
import
warnings
from
io
import
BytesIO
,
StringIO
from
io
import
BytesIO
,
StringIO
# Intrapackage imports
# Intrapackage imports
from
email
import
utils
from
email
import
utils
from
email
import
errors
from
email
import
errors
from
email._policybase
import
compat32
from
email._policybase
import
Policy
,
compat32
from
email
import
charset
as
_charset
from
email
import
charset
as
_charset
from
email._encoded_words
import
decode_b
from
email._encoded_words
import
decode_b
Charset
=
_charset
.
Charset
Charset
=
_charset
.
Charset
...
@@ -1163,3 +1162,6 @@ class EmailMessage(MIMEPart):
...
@@ -1163,3 +1162,6 @@ class EmailMessage(MIMEPart):
super
()
.
set_content
(
*
args
,
**
kw
)
super
()
.
set_content
(
*
args
,
**
kw
)
if
'MIME-Version'
not
in
self
:
if
'MIME-Version'
not
in
self
:
self
[
'MIME-Version'
]
=
'1.0'
self
[
'MIME-Version'
]
=
'1.0'
# Set message_factory on Policy here to avoid a circular import.
Policy
.
message_factory
=
Message
Lib/email/policy.py
Dosyayı görüntüle @
06ed218e
...
@@ -7,6 +7,7 @@ from email._policybase import Policy, Compat32, compat32, _extend_docstrings
...
@@ -7,6 +7,7 @@ from email._policybase import Policy, Compat32, compat32, _extend_docstrings
from
email.utils
import
_has_surrogates
from
email.utils
import
_has_surrogates
from
email.headerregistry
import
HeaderRegistry
as
HeaderRegistry
from
email.headerregistry
import
HeaderRegistry
as
HeaderRegistry
from
email.contentmanager
import
raw_data_manager
from
email.contentmanager
import
raw_data_manager
from
email.message
import
EmailMessage
__all__
=
[
__all__
=
[
'Compat32'
,
'Compat32'
,
...
@@ -82,6 +83,7 @@ class EmailPolicy(Policy):
...
@@ -82,6 +83,7 @@ class EmailPolicy(Policy):
"""
"""
message_factory
=
EmailMessage
utf8
=
False
utf8
=
False
refold_source
=
'long'
refold_source
=
'long'
header_factory
=
HeaderRegistry
()
header_factory
=
HeaderRegistry
()
...
...
Lib/test/test_email/test_parser.py
Dosyayı görüntüle @
06ed218e
import
io
import
io
import
email
import
email
import
unittest
import
unittest
from
email.message
import
Message
from
email.message
import
Message
,
EmailMessage
from
email.policy
import
default
from
email.policy
import
default
from
test.test_email
import
TestEmailBase
from
test.test_email
import
TestEmailBase
...
@@ -39,38 +39,71 @@ class TestParserBase:
...
@@ -39,38 +39,71 @@ class TestParserBase:
# The unicode line splitter splits on unicode linebreaks, which are
# The unicode line splitter splits on unicode linebreaks, which are
# more numerous than allowed by the email RFCs; make sure we are only
# more numerous than allowed by the email RFCs; make sure we are only
# splitting on those two.
# splitting on those two.
msg
=
self
.
parser
(
for
parser
in
self
.
parsers
:
"Next-Line: not
\x85
broken
\r\n
"
with
self
.
subTest
(
parser
=
parser
.
__name__
):
"Null: not
\x00
broken
\r\n
"
msg
=
parser
(
"Vertical-Tab: not
\v
broken
\r\n
"
"Next-Line: not
\x85
broken
\r\n
"
"Form-Feed: not
\f
broken
\r\n
"
"Null: not
\x00
broken
\r\n
"
"File-Separator: not
\x1C
broken
\r\n
"
"Vertical-Tab: not
\v
broken
\r\n
"
"Group-Separator: not
\x1D
broken
\r\n
"
"Form-Feed: not
\f
broken
\r\n
"
"Record-Separator: not
\x1E
broken
\r\n
"
"File-Separator: not
\x1C
broken
\r\n
"
"Line-Separator: not
\u2028
broken
\r\n
"
"Group-Separator: not
\x1D
broken
\r\n
"
"Paragraph-Separator: not
\u2029
broken
\r\n
"
"Record-Separator: not
\x1E
broken
\r\n
"
"
\r\n
"
,
"Line-Separator: not
\u2028
broken
\r\n
"
policy
=
default
,
"Paragraph-Separator: not
\u2029
broken
\r\n
"
)
"
\r\n
"
,
self
.
assertEqual
(
msg
.
items
(),
[
policy
=
default
,
(
"Next-Line"
,
"not
\x85
broken"
),
)
(
"Null"
,
"not
\x00
broken"
),
self
.
assertEqual
(
msg
.
items
(),
[
(
"Vertical-Tab"
,
"not
\v
broken"
),
(
"Next-Line"
,
"not
\x85
broken"
),
(
"Form-Feed"
,
"not
\f
broken"
),
(
"Null"
,
"not
\x00
broken"
),
(
"File-Separator"
,
"not
\x1C
broken"
),
(
"Vertical-Tab"
,
"not
\v
broken"
),
(
"Group-Separator"
,
"not
\x1D
broken"
),
(
"Form-Feed"
,
"not
\f
broken"
),
(
"Record-Separator"
,
"not
\x1E
broken"
),
(
"File-Separator"
,
"not
\x1C
broken"
),
(
"Line-Separator"
,
"not
\u2028
broken"
),
(
"Group-Separator"
,
"not
\x1D
broken"
),
(
"Paragraph-Separator"
,
"not
\u2029
broken"
),
(
"Record-Separator"
,
"not
\x1E
broken"
),
])
(
"Line-Separator"
,
"not
\u2028
broken"
),
self
.
assertEqual
(
msg
.
get_payload
(),
""
)
(
"Paragraph-Separator"
,
"not
\u2029
broken"
),
])
self
.
assertEqual
(
msg
.
get_payload
(),
""
)
class
MyMessage
(
EmailMessage
):
pass
def
test_custom_message_factory_on_policy
(
self
):
for
parser
in
self
.
parsers
:
with
self
.
subTest
(
parser
=
parser
.
__name__
):
MyPolicy
=
default
.
clone
(
message_factory
=
self
.
MyMessage
)
msg
=
parser
(
"To: foo
\n\n
test"
,
policy
=
MyPolicy
)
self
.
assertIsInstance
(
msg
,
self
.
MyMessage
)
def
test_factory_arg_overrides_policy
(
self
):
for
parser
in
self
.
parsers
:
with
self
.
subTest
(
parser
=
parser
.
__name__
):
MyPolicy
=
default
.
clone
(
message_factory
=
self
.
MyMessage
)
msg
=
parser
(
"To: foo
\n\n
test"
,
Message
,
policy
=
MyPolicy
)
self
.
assertNotIsInstance
(
msg
,
self
.
MyMessage
)
self
.
assertIsInstance
(
msg
,
Message
)
# Play some games to get nice output in subTest. This code could be clearer
# if staticmethod supported __name__.
def
message_from_file
(
s
,
*
args
,
**
kw
):
f
=
io
.
StringIO
(
s
)
return
email
.
message_from_file
(
f
,
*
args
,
**
kw
)
class
TestParser
(
TestParserBase
,
TestEmailBase
):
class
TestParser
(
TestParserBase
,
TestEmailBase
):
parser
=
staticmethod
(
email
.
message_from_string
)
parsers
=
(
email
.
message_from_string
,
message_from_file
)
def
message_from_bytes
(
s
,
*
args
,
**
kw
):
return
email
.
message_from_bytes
(
s
.
encode
(),
*
args
,
**
kw
)
def
message_from_binary_file
(
s
,
*
args
,
**
kw
):
f
=
io
.
BytesIO
(
s
.
encode
())
return
email
.
message_from_binary_file
(
f
,
*
args
,
**
kw
)
class
TestBytesParser
(
TestParserBase
,
TestEmailBase
):
class
TestBytesParser
(
TestParserBase
,
TestEmailBase
):
def
parser
(
self
,
s
,
*
args
,
**
kw
):
parsers
=
(
message_from_bytes
,
message_from_binary_file
)
return
email
.
message_from_bytes
(
s
.
encode
(),
*
args
,
**
kw
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
Lib/test/test_email/test_policy.py
Dosyayı görüntüle @
06ed218e
...
@@ -5,6 +5,7 @@ import unittest
...
@@ -5,6 +5,7 @@ import unittest
import
email.policy
import
email.policy
import
email.parser
import
email.parser
import
email.generator
import
email.generator
import
email.message
from
email
import
headerregistry
from
email
import
headerregistry
def
make_defaults
(
base_defaults
,
differences
):
def
make_defaults
(
base_defaults
,
differences
):
...
@@ -23,6 +24,7 @@ class PolicyAPITests(unittest.TestCase):
...
@@ -23,6 +24,7 @@ class PolicyAPITests(unittest.TestCase):
'cte_type'
:
'8bit'
,
'cte_type'
:
'8bit'
,
'raise_on_defect'
:
False
,
'raise_on_defect'
:
False
,
'mangle_from_'
:
True
,
'mangle_from_'
:
True
,
'message_factory'
:
email
.
message
.
Message
,
}
}
# These default values are the ones set on email.policy.default.
# These default values are the ones set on email.policy.default.
# If any of these defaults change, the docs must be updated.
# If any of these defaults change, the docs must be updated.
...
@@ -34,6 +36,7 @@ class PolicyAPITests(unittest.TestCase):
...
@@ -34,6 +36,7 @@ class PolicyAPITests(unittest.TestCase):
'refold_source'
:
'long'
,
'refold_source'
:
'long'
,
'content_manager'
:
email
.
policy
.
EmailPolicy
.
content_manager
,
'content_manager'
:
email
.
policy
.
EmailPolicy
.
content_manager
,
'mangle_from_'
:
False
,
'mangle_from_'
:
False
,
'message_factory'
:
email
.
message
.
EmailMessage
,
})
})
# For each policy under test, we give here what we expect the defaults to
# For each policy under test, we give here what we expect the defaults to
...
@@ -62,20 +65,22 @@ class PolicyAPITests(unittest.TestCase):
...
@@ -62,20 +65,22 @@ class PolicyAPITests(unittest.TestCase):
def
test_defaults
(
self
):
def
test_defaults
(
self
):
for
policy
,
expected
in
self
.
policies
.
items
():
for
policy
,
expected
in
self
.
policies
.
items
():
for
attr
,
value
in
expected
.
items
():
for
attr
,
value
in
expected
.
items
():
self
.
assertEqual
(
getattr
(
policy
,
attr
),
value
,
with
self
.
subTest
(
policy
=
policy
,
attr
=
attr
):
(
"change {} docs/docstrings if defaults have "
self
.
assertEqual
(
getattr
(
policy
,
attr
),
value
,
"changed"
)
.
format
(
policy
))
(
"change {} docs/docstrings if defaults have "
"changed"
)
.
format
(
policy
))
def
test_all_attributes_covered
(
self
):
def
test_all_attributes_covered
(
self
):
for
policy
,
expected
in
self
.
policies
.
items
():
for
policy
,
expected
in
self
.
policies
.
items
():
for
attr
in
dir
(
policy
):
for
attr
in
dir
(
policy
):
if
(
attr
.
startswith
(
'_'
)
or
with
self
.
subTest
(
policy
=
policy
,
attr
=
attr
):
isinstance
(
getattr
(
email
.
policy
.
EmailPolicy
,
attr
),
if
(
attr
.
startswith
(
'_'
)
or
types
.
FunctionType
)):
isinstance
(
getattr
(
email
.
policy
.
EmailPolicy
,
attr
),
continue
types
.
FunctionType
)):
else
:
continue
self
.
assertIn
(
attr
,
expected
,
else
:
"{} is not fully tested"
.
format
(
attr
))
self
.
assertIn
(
attr
,
expected
,
"{} is not fully tested"
.
format
(
attr
))
def
test_abc
(
self
):
def
test_abc
(
self
):
with
self
.
assertRaises
(
TypeError
)
as
cm
:
with
self
.
assertRaises
(
TypeError
)
as
cm
:
...
@@ -237,6 +242,9 @@ class PolicyAPITests(unittest.TestCase):
...
@@ -237,6 +242,9 @@ class PolicyAPITests(unittest.TestCase):
# wins), but that the order still works (right overrides left).
# wins), but that the order still works (right overrides left).
class
TestException
(
Exception
):
pass
class
TestPolicyPropagation
(
unittest
.
TestCase
):
class
TestPolicyPropagation
(
unittest
.
TestCase
):
# The abstract methods are used by the parser but not by the wrapper
# The abstract methods are used by the parser but not by the wrapper
...
@@ -244,40 +252,40 @@ class TestPolicyPropagation(unittest.TestCase):
...
@@ -244,40 +252,40 @@ class TestPolicyPropagation(unittest.TestCase):
# policy was actually propagated all the way to feedparser.
# policy was actually propagated all the way to feedparser.
class
MyPolicy
(
email
.
policy
.
Policy
):
class
MyPolicy
(
email
.
policy
.
Policy
):
def
badmethod
(
self
,
*
args
,
**
kw
):
def
badmethod
(
self
,
*
args
,
**
kw
):
raise
Exception
(
"test"
)
raise
Test
Exception
(
"test"
)
fold
=
fold_binary
=
header_fetch_parser
=
badmethod
fold
=
fold_binary
=
header_fetch_parser
=
badmethod
header_source_parse
=
header_store_parse
=
badmethod
header_source_parse
=
header_store_parse
=
badmethod
def
test_message_from_string
(
self
):
def
test_message_from_string
(
self
):
with
self
.
assertRaisesRegex
(
Exception
,
"^test$"
):
with
self
.
assertRaisesRegex
(
Test
Exception
,
"^test$"
):
email
.
message_from_string
(
"Subject: test
\n\n
"
,
email
.
message_from_string
(
"Subject: test
\n\n
"
,
policy
=
self
.
MyPolicy
)
policy
=
self
.
MyPolicy
)
def
test_message_from_bytes
(
self
):
def
test_message_from_bytes
(
self
):
with
self
.
assertRaisesRegex
(
Exception
,
"^test$"
):
with
self
.
assertRaisesRegex
(
Test
Exception
,
"^test$"
):
email
.
message_from_bytes
(
b
"Subject: test
\n\n
"
,
email
.
message_from_bytes
(
b
"Subject: test
\n\n
"
,
policy
=
self
.
MyPolicy
)
policy
=
self
.
MyPolicy
)
def
test_message_from_file
(
self
):
def
test_message_from_file
(
self
):
f
=
io
.
StringIO
(
'Subject: test
\n\n
'
)
f
=
io
.
StringIO
(
'Subject: test
\n\n
'
)
with
self
.
assertRaisesRegex
(
Exception
,
"^test$"
):
with
self
.
assertRaisesRegex
(
Test
Exception
,
"^test$"
):
email
.
message_from_file
(
f
,
policy
=
self
.
MyPolicy
)
email
.
message_from_file
(
f
,
policy
=
self
.
MyPolicy
)
def
test_message_from_binary_file
(
self
):
def
test_message_from_binary_file
(
self
):
f
=
io
.
BytesIO
(
b
'Subject: test
\n\n
'
)
f
=
io
.
BytesIO
(
b
'Subject: test
\n\n
'
)
with
self
.
assertRaisesRegex
(
Exception
,
"^test$"
):
with
self
.
assertRaisesRegex
(
Test
Exception
,
"^test$"
):
email
.
message_from_binary_file
(
f
,
policy
=
self
.
MyPolicy
)
email
.
message_from_binary_file
(
f
,
policy
=
self
.
MyPolicy
)
# These are redundant, but we need them for black-box completeness.
# These are redundant, but we need them for black-box completeness.
def
test_parser
(
self
):
def
test_parser
(
self
):
p
=
email
.
parser
.
Parser
(
policy
=
self
.
MyPolicy
)
p
=
email
.
parser
.
Parser
(
policy
=
self
.
MyPolicy
)
with
self
.
assertRaisesRegex
(
Exception
,
"^test$"
):
with
self
.
assertRaisesRegex
(
Test
Exception
,
"^test$"
):
p
.
parsestr
(
'Subject: test
\n\n
'
)
p
.
parsestr
(
'Subject: test
\n\n
'
)
def
test_bytes_parser
(
self
):
def
test_bytes_parser
(
self
):
p
=
email
.
parser
.
BytesParser
(
policy
=
self
.
MyPolicy
)
p
=
email
.
parser
.
BytesParser
(
policy
=
self
.
MyPolicy
)
with
self
.
assertRaisesRegex
(
Exception
,
"^test$"
):
with
self
.
assertRaisesRegex
(
Test
Exception
,
"^test$"
):
p
.
parsebytes
(
b
'Subject: test
\n\n
'
)
p
.
parsebytes
(
b
'Subject: test
\n\n
'
)
# Now that we've established that all the parse methods get the
# Now that we've established that all the parse methods get the
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment