In my code I have the following imports:
import email
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
And further in the code:
output = u''.join(
txt.decode(enc or 'iso8859-1') if isinstance(txt, bytes) else txt
for txt, enc in email.Header.decode_header(word)
)
and
email.Encoders.encode_base64(out_message_attachment)
When I run Pylint over this file, I get the following errors:
[E0611] maileater/models.py:4:0 : No name 'MIMEBase' in module 'email'
[E0401] maileater/models.py:4:0 : Unable to import 'email.MIMEBase'
[E0611] maileater/models.py:5:0 : No name 'MIMEMultipart' in module 'email'
[E0401] maileater/models.py:5:0 : Unable to import 'email.MIMEMultipart'
[E0611] maileater/models.py:6:0 : No name 'MIMEText' in module 'email'
[E0401] maileater/models.py:6:0 : Unable to import 'email.MIMEText'
[E1101] maileater/models.py:55:28 : Module 'email' has no 'Header' member
[E1101] maileater/models.py:527:8 : Module 'email' has no 'Encoders' member
However, all of these members are in fact in the email module:
$ ipython
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
Type "copyright", "credits" or "license" for more information.
IPython 4.0.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: from email import MIMEBase, MIMEMultipart, MIMEText, Header, Encoders
In [2]:
Do you really want to exit ([y]/n)? y
pylint 1.7.4,
astroid 1.5.3
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609]
All of this is happening in a virtualenv, and of course, that virtualenv is active for both the Pylint and the iPython run.
from email.MIMEMultipart import MIMEMultipart
Is the correct import for Python 2.x.
According to the Python 3 examples in the documentation, you need:
from email.mime.multipart import MIMEMultipart
The module seems to be doing some "weird" stuff, which might explain a bit.
In the __init__.py in the email library's root folder, we see the following:
_MIMENAMES = [
# email.MIME<old name> -> email.mime.<new name is lowercased old name>
'Audio',
'Base',
'Image',
'Message',
'Multipart',
'NonMultipart',
'Text',
]
# skipping some code
import email.mime
for _name in _MIMENAMES:
importer = LazyImporter('mime.' + _name.lower())
sys.modules['email.MIME' + _name] = importer
setattr(sys.modules['email'], 'MIME' + _name, importer)
setattr(sys.modules['email.mime'], _name, importer)
with the LazyImporter being defined as:
# Lazy loading to provide name mapping from new-style names (PEP 8 compatible
# email 4.0 module names), to old-style names (email 3.0 module names).
import sys
class LazyImporter(object):
def __init__(self, module_name):
self.__name__ = 'email.' + module_name
def __getattr__(self, name):
__import__(self.__name__)
mod = sys.modules[self.__name__]
self.__dict__.update(mod.__dict__)
return getattr(mod, name)
@selinium your suggestion works on Python 2 as well. For now I'm going to solve it like that. Thanks for your input, which prompted me to dig a little deeper.
Given the weird stuff the email module is doing, I think it's safe to assume that we're not going to support this particular use case.
Most helpful comment
from email.MIMEMultipart import MIMEMultipartIs the correct import for Python 2.x.
According to the Python 3 examples in the documentation, you need:
from email.mime.multipart import MIMEMultipart