"email.generator": MIME 문서 생성
*********************************

**소스 코드:** Lib/email/generator.py

======================================================================

가장 일반적인 작업 중 하나는 메시지 객체 구조로 표현되는 전자 우편 메
시지의 평평한 (직렬화된) 버전을 생성하는 것입니다.
"smtplib.SMTP.sendmail()"을 통해 메시지를 보내거나 콘솔에서 메시지를
인쇄하려면 이 작업을 수행해야 합니다. 메시지 객체 구조를 취하고 직렬화
된 표현을 생성하는 것은 제너레이터 클래스의 작업입니다.

"email.parser" 모듈과 마찬가지로 번들 제너레이터의 기능으로 제한되지
않습니다; 처음부터 직접 작성할 수 있습니다. 그러나 번들 제너레이터는
표준 호환 방식으로 대부분 전자 우편을 생성하는 방법을 알고 있고, MIME
과 비 MIME 전자 우편 메시지를 잘 처리하며, 변환 없는 같은 "policy"가
사용된다고 가정할 때 바이트열 지향 구문 분석과 생성 연산이 역이 되도록
설계되었습니다. 즉, "BytesParser" 클래스로 직렬화된 바이트 스트림을 구
문 분석한 다음, "BytesGenerator"를 사용하여 직렬화된 바이트 스트림을
재생성하면 입력과 동일한 출력이 생성됩니다 [1]. (반면에, 프로그램에서
구축한 "EmailMessage"에 제너레이터를 사용하면 기본값이 채워지기 때문에
"EmailMessage" 객체가 변경될 수 있습니다.)

"Generator" 클래스를 사용하면 메시지를 (바이너리가 아닌) 텍스트 직렬화
표현으로 펼칠 수 있지만, 유니코드는 바이너리 데이터를 직접 표현할 수
없기 때문에, "8비트 클린"하지 않은 채널을 통한 전송을 위한 전자 우편
메시지를 인코딩하기 위한 표준 전자 우편 RFC 콘텐츠 전송 인코딩(Content
Transfer Encoding) 기술을 사용하여 메시지를 ASCII 문자만 포함된 것으로
변환해야 합니다.

SMIME 서명된 메시지의 재현성 있는 처리를 위해 "Generator"는
"multipart/signed" 유형의 메시지 파트와 모든 서브 부분에 대해 헤더 접
기를 비활성화합니다.

class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)

   "flatten()" 메서드에 제공된 모든 메시지나 "write()" 메서드에 제공된
   모든 서로게이트 이스케이프 인코딩된 텍스트를 *파일류 객체* *outfp*
   에 쓰는 "BytesGenerator" 객체를 반환합니다. *outfp*는 바이너리 데이
   터를 받아들이는 "write" 메서드를 지원해야 합니다.

   선택적인 *mangle_from_*이 "True"인 경우, 정확한 문자열 ""From ""으
   로 시작하는(즉 줄의 시작에 "From"이 오고 스페이스가 뒤따르는) 본문
   의 모든 줄 앞에 ">" 문자를 넣습니다. *mangle_from_*의 기본값은
   *policy*의 "mangle_from_" 설정값입니다 ("compat32" 정책의 경우
   "True", 다른 모든 경우 "False"입니다). *mangle_from_*은 메시지가 유
   닉스 mbox 형식으로 저장될 때 사용하기 위한 것입니다 ("mailbox"와
   WHY THE CONTENT-LENGTH FORMAT IS BAD를 참조하십시오).

   *maxheaderlen*이 "None"이 아니면, *maxheaderlen*보다 긴 헤더 줄을
   다시 접거나, "0"이면 헤더를 다시 접지 않습니다. *manheaderlen*이
   "None"(기본값)이면, *policy* 설정에 따라 헤더와 기타 메시지 줄을 줄
   바꿈 합니다.

   *policy*가 지정되면, 해당 정책을 사용하여 메시지 생성을 제어합니다.
   *policy*가 "None"(기본값)이면 "flatten"에 전달된 "Message"나
   "EmailMessage" 객체와 연관된 정책을 사용하여 메시지 생성을 제어합니
   다. *policy*가 제어하는 것에 대한 자세한 내용은 "email.policy"를 참
   조하십시오.

   Added in version 3.2.

   버전 3.3에서 변경: *policy* 키워드를 추가했습니다.

   버전 3.6에서 변경: *mangle_from_*과 *maxheaderlen* 매개 변수의 기본
   동작은 정책을 따르는 것입니다.

   flatten(msg, unixfrom=False, linesep=None)

      *msg*를 루트로 하는 메시지 객체 구조의 텍스트 표현을
      "BytesGenerator" 인스턴스가 만들어질 때 지정된 출력 파일에 인쇄
      합니다.

      "policy" 옵션 "cte_type"이 "8bit"(기본값)이면, 하이 비트가 설정
      된 바이트들이 원본에서와같이 재생성되도록 출력이 수정되지 않은
      원본 구문 분석된 메시지의 헤더를 복사하고, 비 ASCII *Content-
      Transfer-Encoding*을 이것을 갖는 모든 본문 파트에서 보존합니다.
      "cte_type"이 "7bit"이면, 하이 비트가 설정된 바이트들을 ASCII 호
      환 *Content-Transfer-Encoding*을 사용하여 필요에 따라 변환합니다
      . 즉, 비 ASCII *Content-Transfer-Encoding*(*Content-Transfer-
      Encoding: 8bit*)을 갖는 파트를 ASCII 호환 *Content-Transfer-
      Encoding*으로 변환하고, 헤더에 있는 RFC 유효하지 않은 비 ASCII
      바이트를 MIME "unknown-8bit" 문자 집합을 사용하여 인코딩하여,
      RFC 호환되게 만듭니다.

      *unixfrom*이 "True"이면, 루트 메시지 객체의 첫 번째 **RFC 5322**
      헤더 앞에 유닉스 mailbox 형식("mailbox"를 참조하십시오)에서 사용
      되는 봉투 헤더 구분자를 인쇄합니다. 루트 객체에 봉투 헤더가 없으
      면, 표준 헤더를 만듭니다. 기본값은 "False"입니다. 서브 파트의 경
      우 봉투 헤더가 인쇄되지 않음에 유의하십시오.

      *linesep*이 "None"이 아니면, 펼쳐진 메시지의 모든 줄 사이의 구분
      자 문자로 사용합니다. *linesep*이 "None"(기본값)이면, *policy*에
      지정된 값을 사용합니다.

   clone(fp)

      정확히 같은 옵션 설정이고 *fp*를 새 *outfp*로 사용하는, 이
      "BytesGenerator" 인스턴스의 독립 클론을 반환합니다.

   write(s)

      "ASCII" 코덱과 "surrogateescape" 에러 처리기를 사용하여 *s*를 인
      코딩하고, "BytesGenerator"의 생성자에 전달된 *outfp*의 *write*
      메서드로 전달합니다.

편의상, "EmailMessage"는 "as_bytes()" 메서드와 "bytes(aMessage)"(일명
"__bytes__()")를 제공하여 메시지 객체의 직렬화된 바이너리 표현 생성을
단순화합니다. 자세한 내용은 "email.message"를 참조하십시오.

문자열은 바이너리 데이터를 나타낼 수 없어서, "Generator" 클래스는 펼쳐
지는 모든 메시지의 바이너리 데이터를 ASCII 호환 *Content-
Transfer_Encoding*으로 변환하여 ASCII 호환 형식으로 변환해야 합니다.
전자 우편 RFC의 용어를 사용하면, 이를 "8비트 클린"이 아닌 I/O 스트림으
로 직렬화하는 "Generator"로 생각할 수 있습니다. 즉, 대부분 응용 프로그
램은 "Generator"가 아닌 "BytesGenerator"를 사용하려고 합니다.

class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)

   "flatten()" 메서드에 제공된 모든 메시지나 "write()" 메서드에 제공된
   텍스트를 *파일류 객체* *outfp*에 쓰는 "Generator" 객체를 반환합니다
   . *outfp*는 문자열 데이터를 받아들이는 "write" 메서드를 지원해야 합
   니다.

   선택적인 *mangle_from_*이 "True"인 경우, 정확한 문자열 ""From ""으
   로 시작하는(즉 줄의 시작에 "From"이 오고 스페이스가 뒤따르는) 본문
   의 모든 줄 앞에 ">" 문자를 넣습니다. *mangle_from_*의 기본값은
   *policy*의 "mangle_from_" 설정값입니다 ("compat32" 정책의 경우
   "True", 다른 모든 경우 "False"입니다). *mangle_from_*은 메시지가 유
   닉스 mbox 형식으로 저장될 때 사용하기 위한 것입니다 ("mailbox"와
   WHY THE CONTENT-LENGTH FORMAT IS BAD를 참조하십시오).

   *maxheaderlen*이 "None"이 아니면, *maxheaderlen*보다 긴 헤더 줄을
   다시 접거나, "0"이면 헤더를 다시 접지 않습니다. *manheaderlen*이
   "None"(기본값)이면, *policy* 설정에 따라 헤더와 기타 메시지 줄을 줄
   바꿈 합니다.

   *policy*가 지정되면, 해당 정책을 사용하여 메시지 생성을 제어합니다.
   *policy*가 "None"(기본값)이면 "flatten"에 전달된 "Message"나
   "EmailMessage" 객체와 연관된 정책을 사용하여 메시지 생성을 제어합니
   다. *policy*가 제어하는 것에 대한 자세한 내용은 "email.policy"를 참
   조하십시오.

   버전 3.3에서 변경: *policy* 키워드를 추가했습니다.

   버전 3.6에서 변경: *mangle_from_*과 *maxheaderlen* 매개 변수의 기본
   동작은 정책을 따르는 것입니다.

   flatten(msg, unixfrom=False, linesep=None)

      *msg*를 루트로 하는 메시지 객체 구조의 텍스트 표현을 "Generator"
      인스턴스가 만들어질 때 지정된 출력 파일에 인쇄합니다.

      "policy" 옵션 "cte_type"이 "8bit"이면, 옵션이 "7bit"로 설정된 것
      처럼 메시지를 생성합니다. (문자열은 비 ASCII 바이트를 나타낼 수
      없기 때문에 필요합니다.) 하이 비트가 설정된 모든 바이트를 ASCII
      호환 *Content-Transfer-Encoding*을 사용하여 필요에 따라 변환합니
      다. 즉, 비 ASCII *Content-Transfer-Encoding*(*Content-Transfer-
      Encoding: 8bit*)을 갖는 파트를 ASCII 호환 *Content-Transfer-
      Encoding*으로 변환하고, 헤더에 있는 RFC 유효하지 않은 비 ASCII
      바이트를 MIME "unknown-8bit" 문자 집합을 사용하여 인코딩하여,
      RFC 호환되게 만듭니다.

      *unixfrom*이 "True"이면, 루트 메시지 객체의 첫 번째 **RFC 5322**
      헤더 앞에 유닉스 mailbox 형식("mailbox"를 참조하십시오)에서 사용
      되는 봉투 헤더 구분자를 인쇄합니다. 루트 객체에 봉투 헤더가 없으
      면, 표준 헤더를 만듭니다. 기본값은 "False"입니다. 서브 파트의 경
      우 봉투 헤더가 인쇄되지 않음에 유의하십시오.

      *linesep*이 "None"이 아니면, 펼쳐진 메시지의 모든 줄 사이의 구분
      자 문자로 사용합니다. *linesep*이 "None"(기본값)이면, *policy*에
      지정된 값을 사용합니다.

      버전 3.2에서 변경: "8bit" 메시지 본문을 다시 인코딩하기 위한 지
      원과 *linesep* 인자가 추가되었습니다.

   clone(fp)

      정확히 같은 옵션을 갖고 *fp*를 새 *outfp*로 사용하는, 이
      "Generator" 인스턴스의 독립 클론을 반환합니다.

   write(s)

      "Generator"의 생성자에 전달된 *outfp*의 *write* 메서드로 *s*를
      씁니다. 이것은 "print()" 함수에서 사용될 "Generator" 인스턴스를
      위해 딱 필요한 만큼의 파일류 API를 제공합니다.

편의상, "EmailMessage"는 "as_string()" 메서드와 "str(aMessage)"(일명
"__str__()")를 제공하여 메시지 객체의 포맷된 문자열 표현 생성을 단순화
합니다. 자세한 내용은 "email.message"를 참조하십시오.

"email.generator" 모듈은 또한 파생 클래스인 "DecodedGenerator"를 제공
하는데, "Generator" 베이스 클래스와 유사하지만, 비 *text* 파트는 직렬
화되지 않고, 대신에 파트에 대한 정보로 채워진 템플릿에서 파생된 문자열
로 출력 스트림에 표시됩니다.

class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)

   "Generator"와 같이 작동하지만, "Generator.flatten()"에 전달된 메시
   지의 서브 파트에 대해, 서브 파트가 메인 유형이 *text*이면, 서브 파
   트의 디코딩된 페이 로드를 인쇄하고, 메인 유형이 *text*가 아니면, 그
   것을 인쇄하지 않고 파트 정보를 사용하여 문자열 *fmt*를 채운 후에 그
   문자열을 인쇄합니다.

   *fmt*를 채우기 위해, "fmt % part_info"를 실행하는데, 여기서
   "part_info"는 다음 키와 값으로 구성된 딕셔너리입니다:

   * "type" -- *text*가 아닌 파트의 전체 MIME 유형

   * "maintype" -- *text*가 아닌 파트의 메인 MIME 유형

   * "subtype" -- *text*가 아닌 파트의 서브 MIME 유형

   * "filename" -- *text*가 아닌 파트의 파일명

   * "description" -- *text*가 아닌 파트와 관련된 설명

   * "encoding" -- *text*가 아닌 파트의 콘텐츠 전송 인코딩(Content
     transfer encoding)

   *fmt*가 "None"이면, 다음 기본 *fmt*를 사용합니다:

      "[Non-text (%(type)s) part of message omitted, filename
      %(filename)s]"

   선택적 *_mangle_from_* 및 *maxheaderlen*은 "Generator" 베이스 클래
   스와 같습니다.

-[ 각주 ]-

[1] 이 문장은 "unixfrom"에 적절한 설정을 사용하고, 자동 조정을 요구하
    는 "email.policy" 설정이 없다고 가정합니다 (예를 들어,
    "refold_source"는 "none"이어야 하며, 이는 기본값이 *아닙*니다). 메
    시지가 RFC 표준을 준수하지 않으면 때때로 구문 분석 에러 복구 중에
    정확한 원본 텍스트에 대한 정보가 손실되므로 100% 사실이 아니기도
    합니다. 가능하다면 이 후자의 경계 사례를 해결하는 것이 목표입니다.
