AttributeError: 'str' object has no attribute 'policy'
Question: I am new to Python. I am trying to make an email script that can send an
email. First, I made a Python script without any classes, just function just
to make sure that the script runs as expected. After I got the expected
result. I am trying to rewrite the script using classes, so as to learn. But I
am getting error, which I don't understand. I don't understand where actually
the problem lies.

Below is the code as well as the screenshot of the error

    
    
    import smtplib
    import os
    import sys
    import mimetypes #for guess mime types of attachment
    
    from email import encoders
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.mime.audio import MIMEAudio
    from email.mime.base import MIMEBase
    from email.mime.image import MIMEImage
    
    class Email(object):
      message = None
      subject = None
      from_address = None
      to_address = None
      body = None
      email_server = None
      attachment = None
    
      def __init__(self,from_address,to_address,subject,body,attachment,email_server):
        self.message = MIMEMultipart()
        self.message['subject'] = subject
        self.message['From'] = from_address
        self.message['TO'] = to_address
        self.body = MIMEText(body, 'plain')
        self.message.attach(body)
        self.email_server = email_server
    
        if attachment is not None:
          self.attachment = attachment
          self.attach_attachment()
    
      def get_message(self):
        return self.message
    
      def send_message(self,auth):
        username, password = auth.get_user_auth_details()
    
        server = smtplib.SMTP(self.email_server)
        server.starttls() #For Encryption
        server.login(username, password)
        server.send_message(self.message)
        server.quit()
    
      def attach_attachment(self):
        self.messaege = self.attachment.set_attachment_type(self.message)
    
    
    
    class Security(object):
      username = ""
      password = ""
    
      def __init__(self,username, password):
        self.username = username
        self.password = password
    
    
      def get_user_auth_details(self):
        return self.username, self.password
    
    class Attachment(object):
      attachment_path = ''
    
      def __init__(self,attachment_path):
        self.attachment_path = attachment_path
    
      def is_directory(self):
        return os.path.isdir(self.attachment_path)
    
      def is_file(self):
        return os.path.isfile(self.attachment_path)
    
      def guess_and_get_attachment_type(self, filenamepath):
        ctype, encoding = mimetypes.guess_type(filenamepath)
    
        if ctype is None or encoding is not None:
          # No guess could be made, or the file is encoded (compressed), so
          # use a generic bag-of-bits type.
          ctype = "application/octet-stream"
    
        maintype , subtype = ctype.split('/' , 1)
    
        if maintype == 'text':
          fp = open(filenamepath)
          attachment = MIMEText(fp.read() , subtype)
          fp.close()
        elif maintype == 'image':
          fp = open(filenamepath , 'rb')
          attachment = MIMEImage(fp.read() , subtype)
          fp.close()
        elif maintype == 'audio':
          fp = open(filenamepath , 'rb')
          attachment = MIMEAudio(fp.read() , subtype)
          fp.close()
        else:
          fp = open(filenamepath , 'rb')
          attachment = MIMEBase(maintype , subtype)
          attachment.set_payload(fp.read()) #Actual message
          fp.close()
          encoders.encode_base64(attachment) # Encode the payload using Base64
    
        return attachment
    
      def set_attachment_type(self,message):
        if(self.is_directory()):
          for filename in os.listdir(self.attachment_path):
            filenamepath = os.path.join(self.attachment_path , filename)
            attachment = self.guess_and_get_attachment_type(filenamepath)
            # Set the filename parameter
            attachment.add_header('Content-Disposition', 'attachment', filename = filenamepath)
            message.attach(attachment)
    
        elif(self.is_file()):
          attachment = self.guess_and_get_attachment_type(self.attachment_path)
          # Set the filename parameter
          attachment.add_header('Content-Disposition', 'attachment', filename = self.attachment_path)
          message.attach(attachment)
        else:
          print("Unable to open file or directory")
    
        return message
    
    
    
    def main():
      #Constants
      GMAIL_SERVER = "smtp.gmail.com:587"
      FROM_ADDRESS = "xyz@gmail.com"
      TO_ADDRESS = "xzy@gmail.com"
    
      auth = Security("xyz@gmail.com" , "MySuperSecretPassword")
      attachment = Attachment("/path/to/attachment/file/or/directory")
      email = Email(FROM_ADDRESS ,TO_ADDRESS, "Hi from class Python" , "OOPs Python at Work!!" ,attachment,GMAIL_SERVER )
    
      email.send_message(auth)
    if __name__ == '__main__':
      main()
    

![enter image description here](http://i.stack.imgur.com/x5mEM.png)


Answer: I changed

    
    
    self.message.attach(body) #In the class email constructor
    

to

    
    
    self.message.attach(self.body) #In the class email constructor
    

and it worked.

I was attaching string type to message instead of MIMEText

