Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 258 – Docutils 설계 사양

Author:
David Goodger <goodger at python.org>
Discussions-To:
Doc-SIG list
Status:
Rejected
Type:
Standards Track
Requires:
256, 257
Created:
31-May-2001
Post-History:
13-Jun-2001

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

거부 통지

이는 현재 독립된 docutils를 위한 흥미로운 설계 문서로 활용될 수 있지만, 더 이상 표준 라이브러리에 포함될 예정이 아닙니다.

초록

이 PEP는 Python Docstring Processing System(DPS)인 Docutils의 설계 문제와 구현 세부 사항을 문서화합니다. DPS의 근거와 고수준 개념은 PEP 256의 “Docstring Processing System Framework”에 문서화되어 있습니다. “Docstring PEP 로드맵”은 PEP 256도 참조하십시오.

Docutils는 구성 요소를 쉽게 교체할 수 있도록 모듈식으로 설계되고 있습니다. 또한 Docutils는 Python 독스트링 처리에만 국한되지 않으며, 여러 컨텍스트에서 독립형 문서도 처리합니다.

이 PEP에는 핵심 Python 언어의 변경이 필요하지 않습니다. 산출물은 표준 라이브러리용 패키지와 해당 문서로 구성됩니다.

사양

Docutils 프로젝트 모델

프로젝트 구성 요소와 데이터 흐름:

                 +---------------------------+
                 |        Docutils:          |
                 | docutils.core.Publisher,  |
                 | docutils.core.publish_*() |
                 +---------------------------+
                  /            |            \
                 /             |             \
        1,3,5   /        6     |              \ 7
       +--------+       +-------------+       +--------+
       | READER | ----> | TRANSFORMER | ====> | WRITER |
       +--------+       +-------------+       +--------+
        /     \\                                  |
       /       \\                                 |
 2    /      4  \\                             8  |
+-------+   +--------+                        +--------+
| INPUT |   | PARSER |                        | OUTPUT |
+-------+   +--------+                        +--------+

각 구성 요소 위의 숫자는 문서 데이터가 거치는 경로를 나타냅니다. Reader와 Parser 사이 및 Transformer와 Writer 사이의 이중 너비 선은 이러한 경로를 따라 전송되는 데이터가 표준(순수하고 확장되지 않은) Docutils 문서 트리여야 함을 나타냅니다. 단일 너비 선은 내부 트리 확장 또는 전혀 관련 없는 표현이 가능하지만, 양쪽 끝에서 이를 지원해야 함을 의미합니다.

퍼블리셔

docutils.core 모듈에는 “Publisher” 퍼사드 클래스와 여러 편의 함수가 포함되어 있습니다. “publish_cmdline()”은 명령줄 프런트엔드용이고, “publish_file()”은 파일과 유사한 I/O를 프로그래밍 방식으로 사용하기 위한 것이며, “publish_string()”은 문자열 I/O를 프로그래밍 방식으로 사용하기 위한 것입니다. Publisher 클래스는 Docutils 시스템의 고수준 논리를 캡슐화합니다. Publisher 클래스는 Publisher.publish() 메서드에 의해 제어되는 처리 전반을 담당합니다.

  1. 내부 설정(구성 파일 및 명령줄 옵션을 포함할 수 있음)과 I/O 객체를 설정합니다.
  2. Reader 객체를 호출하여 소스 Input 객체에서 데이터를 읽고 Parser 객체로 데이터를 구문 분석합니다. 문서 객체가 반환됩니다.
  3. 문서에 연결된 Transformer 객체를 통해 변환을 설정하고 적용합니다.
  4. 문서를 최종 출력 형식으로 변환하고 형식이 지정된 데이터를 대상 Output 객체에 기록하는 Writer 객체를 호출합니다. Output 객체에 따라 출력은 Writer에서 반환된 다음 publish() 메서드에서 반환될 수 있습니다.

구성 요소 이름을 사용하여 “publish” 함수를 호출하거나 “Publisher” 객체를 인스턴스화하면 기본 동작이 수행됩니다. 사용자 지정 동작을 위해(구성 요소 설정을 사용자 지정하려면) 먼저 사용자 지정 구성 요소 객체를 만들고, them을 Publisher 또는 publish_* 편의 함수에 전달하십시오.

리더

리더는 입력 컨텍스트(데이터가 어디에서 오는지)를 이해하고, 전체 입력 또는 개별 “청크”를 파서에 보내며, 청크를 다시 하나의 일관된 전체로 결합할 수 있도록 컨텍스트를 제공합니다.

각 리더는 “Reader” 클래스를 내보내며 “read” 메서드를 제공하는 모듈 또는 패키지입니다. 기본 “Reader” 클래스는 docutils/readers/__init__.py 모듈에서 찾을 수 있습니다.

대부분의 리더에는 사용할 파서를 지정해야 합니다. 현재까지는(아래 예제 목록을 참조하십시오) Python Source Reader(“PySource”; 아직 불완전함)만 자체적으로 파서를 결정할 수 있습니다.

책임:

  • 소스 I/O에서 입력 텍스트를 가져옵니다.
  • 새로운 Document Tree 루트와 함께 입력 텍스트를 파서에 전달합니다.

예:

  • 독립 실행형(Raw/Plain): 텍스트 파일을 읽고 처리하기만 합니다. 리더에 사용할 파서를 지정해야 합니다.

    “Standalone Reader”는 docutils.readers.standalone 모듈에 구현되어 있습니다.

  • Python Source: 아래의 Python Source Reader를 참조하십시오. 이 리더는 현재 Docutils 샌드박스에서 개발 중입니다.
  • 이메일: RFC 822 헤더, 인용 발췌문, 서명, MIME 부분입니다.
  • PEP: RFC 822 헤더, “PEP xxxx” 및 “RFC xxxx”를 URI로 변환합니다. “PEP Reader”는 docutils.readers.pep 모듈에 구현되어 있습니다. PEP 287PEP 12를 참조하십시오.
  • 위키: 트랜스폼에 통합된 “wiki links”의 전역 참조 조회입니다. (CamelCase만 허용합니까, 아니면 제한이 없습니까?) 느슨한 들여쓰기입니까?
  • 웹 페이지: 독립 실행형과 같지만 메타 필드를 메타 태그로 인식합니다. 어떤 종류의 템플릿을 지원합니까? (<body> 뒤, </body> 앞?)
  • FAQ: 구조화된 “질문 및 답변” 구성입니다.
  • 복합 문서: 장을 하나의 책으로 병합합니다. 마스터 매니페스트 파일입니까?

파서

파서는 입력을 분석하고 Docutils Document Tree를 생성합니다. 파서는 데이터의 출처나 목적지를 알지도, 신경 쓰지도 않습니다.

각 입력 파서는 “Parser” 클래스를 내보내며 “parse” 메서드를 제공하는 모듈 또는 패키지입니다. 기본 “Parser” 클래스는 docutils/parsers/__init__.py 모듈에서 찾을 수 있습니다.

책임: 원시 입력 텍스트와 독트리 루트 노드가 주어지면, 입력 텍스트를 파싱하여 독트리를 채웁니다.

예: 현재까지 구현된 유일한 파서는 reStructuredText 마크업용 파서입니다. 이 파서는 docutils/parsers/rst/ 패키지에 구현되어 있습니다.

다른 파서의 개발 및 통합도 가능하며 권장됩니다.

트랜스포머

docutils/transforms/__init__.py의 Transformer 클래스는 변환을 저장하고 문서에 적용합니다. 모든 새 문서 트리에는 트랜스포머 객체가 연결됩니다. Publisher_는 저장된 모든 변환을 문서 트리에 적용하기 위해 Transformer.apply_transforms()를 호출합니다. 변환은 문서 트리를 한 형식에서 다른 형식으로 변경하거나, 트리에 추가하거나, 트리에서 제거합니다. 변환은 참조와 각주 번호를 해결하고, 해석된 텍스트를 처리하며, 그 밖의 컨텍스트에 민감한 처리를 수행합니다.

일부 변환은 컴포넌트(Reader, Parser, Writer, Input, Output)에만 해당합니다. 표준 컴포넌트별 변환은 컴포넌트 클래스의 default_transforms속성에 지정됩니다. Reader가 처리를 완료한 후 Publisher_는 컴포넌트 목록과 함께 Transformer.populate_from_components()를 호출하고, 모든 기본 변환이 저장됩니다.

각 변환은 docutils/transforms/ 패키지의 모듈에 있는 클래스이며, docutils.transforms.Transform의 서브클래스입니다. 각 변환 클래스에는 default_priority속성이 있으며, Transformer는 이 속성을 사용하여 낮은 우선순위에서 높은 우선순위 순으로 변환을 적용합니다. Transformer 객체에 변환을 추가할 때 기본 우선순위를 재정의할 수 있습니다.

Transformer의 책임:

  • 우선순위 순으로 변환을 문서 트리에 적용합니다.
  • 컴포넌트 객체에 대한 컴포넌트 유형 이름(‘reader’, ‘writer’ 등)의 매핑을 저장합니다. 특정 변환(예: “components.Filter”)은 적합성을 판단하기 위해 이를 사용합니다.

변환의 책임:

  • 닥트리를 제자리에서 수정하며, 하나의 구조를 순수하게 다른 구조로 변환하거나 닥트리 및/또는 외부 데이터를 기반으로 새 구조를 추가합니다.

변환의 예(docutils/transforms/ 패키지):

  • frontmatter.DocInfo: 문서 메타데이터(서지 정보)를 변환합니다.
  • references.AnonymousHyperlinks: 이름 없는 참조를 해당 대상에 연결합니다.
  • parts.Contents: 문서의 목차를 생성합니다.
  • document.Merger: 여러 개의 내용이 채워진 닥트리를 하나로 결합합니다. (아직 구현되지 않았거나 충분히 이해되지 않았습니다.)
  • document.Splitter: 문서를 트리 구조의 하위 문서로 분할하며, 섹션별로 분할할 수도 있습니다. 참조를 적절하게 변환해야 합니다. (구현되지 않았을 뿐만 아니라 전혀 이해되지도 않았습니다.)
  • components.Filter: 특정 Docutils 컴포넌트에 의존하는 요소를 포함하거나 제외합니다.

Writer

Writer는 최종 출력(HTML, XML, TeX 등)을 생성합니다. Writer는 내부 Document Tree구조를 최종 데이터 형식으로 변환하며, 먼저 Writer별 transforms를 실행할 수도 있습니다.

문서가 Writer에 전달될 때에는 최종 형식이어야 합니다. Writer의 작업은 단순히(그리고 오직) Docutils 닥트리 구조를 대상 형식으로 변환하는 것입니다. 일부 작은 변환이 필요할 수 있지만, 그러한 변환은 국소적이고 형식에 특화된 것이어야 합니다.

각 라이터는 “Writer” 클래스를 내보내며 “write” 메서드를 제공하는 모듈 또는 패키지입니다. 기본 “Writer” 클래스는 docutils/writers/__init__.py 모듈에서 찾을 수 있습니다.

책임:

  • 독트리(들)를 특정 출력 형식으로 변환합니다.
    • 참조를 형식에 맞는 고유 형식으로 변환합니다.
  • 변환된 출력을 대상 I/O에 씁니다.

예:

  • XML: 다음과 같은 다양한 형식이 있습니다.
    • Docutils XML(내부 문서 트리를 표현하며, docutils.writers.docutils_xml로 구현됩니다).
    • DocBook(Docutils 샌드박스에서 구현 중입니다).
  • HTML(docutils.writers.html4css1로 구현된 XHTML입니다).
  • PDF(Docutils 샌드박스에서 ReportLabs 인터페이스를 개발 중입니다).
  • TeX(샌드박스에서 LaTeX Writer를 구현 중입니다).
  • Docutils 고유의 의사 XML(docutils.writers.pseudoxml로 구현되며 테스트에 사용됩니다).
  • 일반 텍스트
  • reStructuredText입니까?

입력/출력

I/O 클래스는 저수준 입력 및 출력을 위한 통합 API를 제공합니다. 다양한 입력/출력 메커니즘을 위한 서브클래스가 존재하게 됩니다. 그러나 이는 구현 세부 사항으로 간주할 수 있습니다. 대부분의 애플리케이션은 Publisher와 연결된 편의 함수 중 하나를 사용하면 충분합니다.

I/O 클래스는 현재 예비 단계에 있으며, 아직 해야 할 일이 많습니다. 문제:

  • API에서 다중 파일 입력(파일 및 디렉터리)을 어떻게 나타내야 합니까?
  • 다중 파일 출력을 어떻게 나타내야 합니까? 출력 배포 유형마다 하나씩 “Writer” 변형을 두는 것이 좋을까요? 아니면 관련 변환을 포함하는 Output 객체를 두어야 할까요?

책임:

  • 입력 소스(Input 객체)에서 데이터를 읽거나 출력 대상(Output 객체)에 데이터를 씁니다.

입력 소스의 예:

  • 디스크의 단일 파일 또는 스트림(docutils.io.FileInput으로 구현됩니다).
  • 디스크의 여러 파일(MultiFileInput?).
  • Python 소스 파일: 모듈 및 패키지입니다.
  • 클라이언트 애플리케이션에서 수신한 Python 문자열(docutils.io.StringInput로 구현됩니다)입니다.

출력 대상의 예시는 다음과 같습니다:

  • 디스크의 단일 파일 또는 스트림(docutils.io.FileOutput로 구현됩니다)입니다.
  • 디스크의 디렉터리 및 파일 트리입니다.
  • 클라이언트 애플리케이션으로 반환되는 Python 문자열(docutils.io.StringOutput로 구현됩니다)입니다.
  • 출력이 없습니다. 일반 출력의 일부만 사용해야 하는 프로그래밍 방식의 애플리케이션에 유용합니다(docutils.io.NullOutput로 구현됩니다).
  • 메모리의 단일 트리 형태 데이터 구조입니다.
  • 메모리의 다른 데이터 구조 집합입니다.

Docutils 패키지 구조입니다.

  • 패키지 “docutils”입니다.
    • 모듈 “__init__.py”에는 클래스 “Component”(Docutils 구성 요소의 베이스 클래스), 클래스 “SettingsSpec”(런타임 설정 지정에 사용되는 베이스 클래스(docutils.frontend에서 사용)) 및 클래스 “TransformSpec”(변환 지정에 사용되는 베이스 클래스)가 포함되어 있습니다.
    • 모듈 “docutils.core”에는 파사드 클래스 “Publisher”와 편의 함수가 포함되어 있습니다. 위의 Publisher를 참조하십시오.
    • 모듈 “docutils.frontend”는 프로그래밍 방식의 사용과 프런트엔드 도구를 위한 런타임 설정 지원을 제공합니다(구성 파일 지원 및 명령줄 인자와 옵션 처리를 포함합니다).
    • 모듈 “docutils.io”는 저수준 입력 및 출력에 대한 통합 API를 제공합니다. 위의 Input/Output을 참조하십시오.
    • 모듈 “docutils.nodes”에는 Docutils 문서 트리 요소 클래스 라이브러리와 트리 순회를 위한 Visitor 패턴 베이스 클래스가 포함되어 있습니다. 아래의 Document Tree를 참조하십시오.
    • 모듈 “docutils.statemachine”에는 정규 표현식 기반 텍스트 필터와 파서에 특화된 유한 상태 머신이 포함되어 있습니다. reStructuredText 파서 구현은 이 모듈을 기반으로 합니다.
    • 모듈 “docutils.urischemes”에는 알려진 URI 스킴(“http”, “ftp”, “mail” 등)의 매핑이 포함되어 있습니다.
    • 모듈 “docutils.utils”에는 유틸리티 함수와 클래스가 포함되어 있으며, 로거 클래스(“Reporter”; 아래의 Error Handling을 참조하십시오)도 포함됩니다.
    • 패키지 “docutils.parsers”: 마크업 Parsers.
      • 함수 “get_parser_class(parser_name)”는 이름으로 파서 모듈을 반환합니다. 클래스 “Parser”는 특정 파서의 베이스 클래스입니다. (docutils/parsers/__init__.py)
      • 패키지 “docutils.parsers.rst”: reStructuredText 파서입니다.
      • 대체 마크업 파서를 추가할 수 있습니다.

      위의 Parsers를 참조하십시오.

    • 패키지 “docutils.readers”: 컨텍스트 인식 입력 리더입니다.
      • 함수 “get_reader_class(reader_name)”는 이름 또는 별칭으로 리더 모듈을 반환합니다. 클래스 “Reader”는 특정 리더의 베이스 클래스입니다. (docutils/readers/__init__.py)
      • 모듈 “docutils.readers.standalone”은 독립 문서 파일을 읽습니다.
      • 모듈 “docutils.readers.pep”은 PEP(파이썬 개선 제안)를 읽습니다.
      • 다음 항목을 위한 리더를 추가할 예정입니다: 파이썬 소스 코드(구조 및 독스트링), 이메일, FAQ, 그리고 아마도 Wiki 및 기타 항목입니다.

      위의 Readers를 참조하십시오.

    • 패키지 “docutils.writers”: 출력 형식 작성기입니다.
      • 함수 “get_writer_class(writer_name)”은 이름으로 작성기 모듈을 반환합니다. 클래스 “Writer”는 특정 작성기의 기반 클래스입니다. (docutils/writers/__init__.py)
      • 모듈 “docutils.writers.html4css1”은 HTML 4.01 및 CSS1용 간단한 하이퍼텍스트 마크업 언어 문서 트리 작성기입니다.
      • 모듈 “docutils.writers.docutils_xml”은 내부 문서 트리를 XML 형식으로 작성합니다.
      • 모듈 “docutils.writers.pseudoxml”은 간단한 내부 문서 트리 작성기이며, 들여쓰기된 의사 XML을 작성합니다.
      • 다음 작성기를 추가할 예정입니다: HTML 3.2 또는 4.01-loose, XML(DocBook과 같은 다양한 형식), PDF, TeX, 일반 텍스트, reStructuredText, 그리고 아마도 기타 형식입니다.

      위의 Writers를 참조하십시오.

    • 패키지 “docutils.transforms”: 트리 변환 클래스입니다.
      • 클래스 “Transformer”는 변환을 저장하고 문서 트리에 적용합니다. (docutils/transforms/__init__.py)
      • 클래스 “Transform”은 특정 변환의 기반 클래스입니다. (docutils/transforms/__init__.py)
      • 각 모듈에는 관련 변환 클래스가 포함되어 있습니다.

      위의 Transforms를 참조하십시오.

    • 패키지 “docutils.languages”: 언어 모듈에는 언어에 종속된 문자열과 매핑이 포함되어 있습니다. 이러한 모듈은 언어 식별자(아래의 Choice of Docstring Format에 정의됨)를 기준으로 이름을 지정하며, 대시를 밑줄로 변환합니다.
      • 함수 “get_language(language_code)”는 일치하는 언어 모듈을 반환합니다. (docutils/languages/__init__.py)
      • 모듈: en.py(영어), de.py(독일어), fr.py(프랑스어), it.py(이탈리아어), sk.py(슬로바키아어), sv.py(스웨덴어)입니다.
      • 다른 언어도 추가할 예정입니다.
  • 서드파티 모듈: “extras” 디렉터리입니다. 이러한 모듈은 Python 설치에 이미 존재하지 않는 경우에만 설치됩니다.
    • extras/optparse.pyextras/textwrap.py는 옵션 구문 분석과 명령줄 도움말을 제공합니다. 편의를 위해 포함된 Greg Ward의 http://optik.sf.net/ 프로젝트에서 가져왔습니다.
    • extras/roman.py에는 로마 숫자 변환 루틴이 포함되어 있습니다.

프런트엔드 도구

tools/ 디렉터리에는 일반적인 Docutils 처리를 위한 여러 프런트엔드가 포함되어 있습니다. 자세한 내용은 Docutils Front-End Tools를 참조하십시오.

문서 트리

Docutils는 구성 요소 간의 인터페이스에서 내부적으로 단일 중간 데이터 구조를 사용하며, 이 구조는 docutils.nodes모듈에 정의되어 있습니다. 위의 Docutils Project Model다이어그램에 제시된 것처럼 이 데이터 구조를 어떤 구성 요소에서든 내부적으로 사용해야 하는 것은 아니며, 단지 구성 요소 사이에서 사용하면 됩니다.

사용자 정의 노드 유형은 (a) 변환이 해당 노드가 실제 Writer에 도달하기 전에 표준 Docutils 노드로 변환하거나, (b) 사용자 정의 노드가 특정 Writer에서 명시적으로 지원되고 필터링된 “pending” 노드로 래핑되는 경우 허용됩니다. 조건 (a)의 예로는 아래에 설명된 Python Source Reader가 있으며, 여기에서는 “stylist” 변환이 사용자 정의 노드를 변환합니다. HTML <meta> 태그는 조건 (b)의 예이며, HTML Writer에서는 지원되지만 다른 Writer에서는 지원되지 않습니다. reStructuredText의 “meta” 지시문은 포함된 “meta” 노드를 HTML 호환 Writer만 처리할 수 있다는 정보를 포함하는 “pending” 노드를 생성합니다. “pending” 노드는 호출한 Writer가 HTML을 지원하는지 확인하는 docutils.transforms.components.Filter 변환에 의해 해결되며, 지원하지 않는 경우 “pending” 노드와 그 안에 포함된 “meta” 노드가 문서에서 제거됩니다.

문서 트리 데이터 구조는 DOM 트리와 유사하지만, DOM의 일반 노드 대신 특정 노드 이름(클래스)을 사용합니다. 스키마는 두 부분으로 구성되는 XML DTD(eXtensible Markup Language Document Type Definition)에 문서화되어 있습니다:

DTD는 다양한 입력 및 출력 형식에 적합한 풍부한 요소 집합을 정의합니다. DTD는 원래 입력 텍스트 또는 그에 상응하는 합리적인 복제물을 재구성하는 데 필요한 모든 정보를 보존합니다.

자세한 내용은 The Docutils Document Tree를 참조하십시오(불완전).

오류 처리

파서가 마크업에서 오류를 발견하면 시스템 메시지(DTD 요소 “system_message”)를 삽입합니다. 시스템 메시지에는 다섯 가지 수준이 있습니다:

  • Level-0, “DEBUG”: 내부 보고 문제입니다. 처리에 영향을 주지 않습니다. Level-0 시스템 메시지는 다른 메시지와 별도로 처리됩니다.
  • Level-1, “INFO”: 무시할 수 있는 사소한 문제입니다. 처리에 미치는 영향이 거의 없거나 전혀 없습니다. 일반적으로 Level-1 시스템 메시지는 보고되지 않습니다.
  • Level-2, “WARNING”: 해결해야 하는 문제입니다. 무시하면 출력에 사소한 문제가 발생할 수 있습니다. 일반적으로 Level-2 시스템 메시지는 보고되지만 처리를 중단하지는 않습니다
  • Level-3, “ERROR”: 해결해야 하는 중대한 문제입니다. 무시하면 출력에 예측할 수 없는 오류가 포함됩니다. 일반적으로 Level-3 시스템 메시지는 보고되지만 처리를 중단하지는 않습니다
  • Level-4, “SEVERE”: 반드시 해결해야 하는 치명적인 오류입니다. 일반적으로 Level-4 시스템 메시지는 처리 중단을 일으키는 예외로 변환됩니다. 무시하면 출력에 심각한 오류가 포함됩니다.

초기 메시지 수준은 독립적으로 고안되었지만 VMS error condition severity levels와 밀접하게 대응하며, 수준 1부터 4까지의 따옴표 안 이름은 VMS에서 차용되었습니다. 이후 오류 처리는 log4j project의 영향을 받았습니다.

Python 소스 리더

Python 소스 리더(“PySource”)는 Python 소스 파일을 읽고, 맥락에 맞게 독스트링을 추출한 다음, 독스트링을 구문 분석하고 연결하여 일관된 전체로 조립하는 Docutils 구성 요소입니다. 이는 주요하고 복잡한 구성 요소이며, 현재 Docutils 샌드박스에서 실험적으로 개발되고 있습니다. 여기에서는 상위 수준의 설계 문제를 제시합니다.

처리 모델

이 모델은 경험과 발견을 반영하면서 시간이 지남에 따라 발전합니다.

  1. PySource 리더는 Input 클래스를 사용하여 Python 패키지와 모듈을 읽어 문자열 트리로 만듭니다.
  2. Python 모듈을 구문 분석하여 문자열 트리를 독스트링 노드가 포함된 추상 구문 트리로 변환합니다.
  3. 추상 구문 트리를 패키지/모듈의 내부 표현으로 변환합니다. 코드 구조 세부 정보와 함께 독스트링을 추출합니다. 아래의 AST Mining을 참조하십시오. 6단계에서 조회할 수 있도록 네임스페이스를 구성합니다.
  4. 독스트링을 하나씩 구문 분석하여 표준 Docutils 독트리를 생성합니다.
  5. PySource는 각각의 독스트링 독트리를 패키지/모듈/클래스 구조에 대응하는 Python 전용 사용자 정의 Docutils 트리로 조립합니다. 이는 리더 전용 사용자 정의 내부 표현입니다(Docutils Python Source DTD를 참조하십시오). 네임스페이스를 병합해야 합니다. Python 식별자와 하이퍼링크 대상이 이에 해당합니다.
  6. 독스트링(해석된 텍스트)에서 Python 식별자로 연결되는 상호 참조를 Python 네임스페이스 조회 규칙에 따라 해결합니다. 아래의 Identifier Cross-References를 참조하십시오.
  7. “Stylist” 변환은 사용자 정의 독트리에 적용되고(Transformer_를 통해), 표준 노드를 기본 요소로 사용하여 사용자 정의 노드를 렌더링하며, 표준 문서 트리를 출력합니다. 아래의 Stylist Transforms를 참조하십시오.
  8. 기타 변환은 Transformer_에 의해 표준 독트리에 적용됩니다.
  9. 표준 독트리를 Writer로 보내 문서를 구체적인 형식(HTML, PDF 등)으로 변환합니다.
  10. Writer는 Output 클래스를 사용하여 결과 데이터를 대상(디스크 파일, 디렉터리와 파일 등)에 기록합니다.

AST 마이닝

추상 구문 트리 마이닝 코드를 작성하거나 조정하여, 구문 분석된 Python 모듈을 스캔하고 다음 모든 객체의 이름, 독스트링(속성 독스트링과 추가 독스트링 포함. 아래 참조), 추가 정보(아래 괄호 안에 표시)를 포함하는 정렬된 트리를 반환합니다.

  • 패키지
  • 모듈
  • 모듈 속성(+ 초기 값)
  • 클래스(+ 상속)
  • 클래스 속성(+ 초기 값)
  • 인스턴스 속성(+ 초기 값)
  • 메서드(+ 매개변수 및 기본값)
  • 함수(+ 매개변수 및 기본값)

(주석도 추출합니까? 예를 들어, 모듈 시작 부분의 주석은 서지 필드 목록을 작성하기에 좋은 위치입니다.)

해석된 텍스트 상호 참조를 평가하려면 위에 언급한 각각에 대한 네임스페이스도 필요합니다.

2001-08-14에 시작된 python-dev/docstring-develop 스레드 “AST mining”을 참조하십시오.

독스트링 추출 규칙

  1. 검사할 항목:
    1. 문서화하는 모듈에 “__all__” 변수가 있으면, “__all__”에 나열된 식별자만 독스트링에 대해 검사합니다.
    2. __all__”이 없으면 모든 식별자를 검사합니다. 단, 이름이 비공개인 식별자(이름이 “_”로 시작하지만 “__”로 시작하고 끝나지는 않는 식별자)는 제외합니다.
    3. 1a와 1b는 런타임 설정으로 재정의할 수 있습니다.
  2. 위치:

    독스트링은 문자열 리터럴 표현식이며, Python 모듈 내 다음 위치에서 인식됩니다.

    1. 모듈, 함수 정의, 클래스 정의 또는 메서드 정의의 시작 부분에서, 모든 주석 뒤에 위치한 경우입니다. 이것이 Python __doc__ 특성의 표준입니다.
    2. 모듈, 클래스 정의 또는 __init__ 메서드 정의의 최상위 수준에서 단순 할당 직후에, 모든 주석 뒤에 위치한 경우입니다. 아래의 Attribute Docstrings를 참조하십시오.
    3. (a)와 (b)의 독스트링 직후에 나오는 추가 문자열 리터럴은 인식되고, 추출되며, 연결됩니다. 아래의 Additional Docstrings를 참조하십시오.
    4. @@@ 2.2 스타일의 “properties”에 속성 독스트링을 사용합니까? 구문이 나올 때까지 기다립니까?
  3. 방법:

    가능한 경우 Python 모듈은 임포트하지 말고 Docutils로 구문 분석해야 합니다. 여기에는 몇 가지 이유가 있습니다.

    • 신뢰할 수 없는 코드를 임포트하는 것은 본질적으로 안전하지 않습니다.
    • 임포트된 모듈을 인트로스펙션으로 검사하면 주석과 정의 순서 등 소스의 정보가 손실됩니다.
    • 독스트링은 바이트코드 컴파일러가 문자열 리터럴 표현식을 무시하는 위치(위의 2b와 2c)에서도 인식되어야 하며, 이는 모듈을 임포트하면 이러한 독스트링이 손실된다는 의미입니다.

    물론 “parser” 라이브러리 모듈과 같은 표준 Python 구문 분석 도구를 사용해야 합니다.

    모듈의 Python 소스 코드를 사용할 수 없거나(즉, .pyc 파일만 존재하는 경우), C 확장 모듈인 경우에는 독스트링에 액세스하려면 모듈을 임포트하는 수밖에 없으며, 그에 따른 모든 제한을 감수해야 합니다.

속성 독스트링과 추가 독스트링은 Python 바이트코드 컴파일러에서 무시되므로, 이를 사용해도 네임스페이스 오염이나 런타임 부하 증가는 발생하지 않습니다. 이러한 독스트링은 __doc__이나 다른 어떤 특성에도 할당되지 않습니다. 모듈의 초기 구문 분석으로 인해 성능이 약간 저하될 수 있습니다.

속성 독스트링

(이는 PEP 224의 단순화된 버전입니다.)

할당 문 바로 뒤에 오는 문자열 리터럴은 다음 조건에서 문서 문자열 추출 메커니즘에 의해 할당 문의 대상에 대한 문서 문자열로 해석됩니다:

  1. 할당은 다음 컨텍스트 중 하나에 있어야 합니다:
    1. 모듈의 최상위 수준(즉, 반복문이나 조건문과 같은 복합 문 안에 중첩되지 않은 경우): 모듈 속성:
    2. 클래스 정의의 최상위 수준: 클래스 속성:
    3. 클래스의 “__init__” 메서드 정의의 최상위 수준: 인스턴스 속성입니다. 다른 메서드에서 할당되는 인스턴스 속성은 구현 세부 사항으로 간주합니다. (@@@ __new__ 메서드?)
    4. 모듈 또는 클래스 정의의 최상위 수준에서 이루어지는 함수 속성 할당입니다.

    위의 각 컨텍스트는 최상위 수준(즉, 정의의 가장 바깥쪽 suite)에 있으므로, 조건부로 또는 반복문 안에서 할당되는 속성에 대해 더미 할당을 배치해야 할 수도 있습니다.

  2. 할당은 여러 대상의 리스트나 튜플이 아니라 단일 대상에 이루어져야 합니다.
  3. 대상의 형식:
    1. 위의 컨텍스트 1a 및 1b에서는 대상이 단순 식별자여야 합니다(점으로 구분된 식별자, 첨자화된 표현식 또는 슬라이스된 표현식이 아니어야 합니다).
    2. 컨텍스트 1c에서는 대상이 “self.attrib” 형식이어야 하며, 여기서 “self”는 “__init__” 메서드의 첫 번째 매개변수(인스턴스 매개변수)에 해당하고 “attrib”은 3a에서와 같은 단순 식별자여야 합니다.
    3. 컨텍스트 1d에서는 대상이 “name.attrib” 형식이어야 하며, 여기서 “name”은 이미 정의된 함수 또는 메서드 이름에 해당하고 “attrib”은 3a에서와 같은 단순 식별자여야 합니다.

할당과 문서 문자열의 연결을 강조하기 위해 속성 문서 문자열 뒤에 빈 줄을 사용할 수 있습니다.

예제:

g = 'module attribute (module-global variable)'
"""This is g's docstring."""

class AClass:

    c = 'class attribute'
    """This is AClass.c's docstring."""

    def __init__(self):
        """Method __init__'s docstring."""

        self.i = 'instance attribute'
        """This is self.i's docstring."""

def f(x):
    """Function f's docstring."""
    return x**2

f.a = 1
"""Function attribute f.a's docstring."""
추가 문서 문자열

(이 아이디어는 PEP 216에서 차용했습니다.)

많은 프로그래머는 API 문서에 문서 문자열을 광범위하게 사용하기를 원합니다. 그러나 문서 문자열은 실행 중인 프로그램에서 공간을 차지하므로, 일부 프로그래머는 코드를 “비대하게 만드는 것”을 꺼립니다. 또한 __doc__이 표시되는 대화형 환경에는 모든 API 문서가 적용되는 것은 아닙니다.

Docutils의 문서 문자열 추출 도구는 정의의 시작 부분 또는 단순 할당 뒤에 나타나는 모든 문자열 리터럴 표현식을 연결합니다. 정의에서 첫 번째 문자열만 __doc__으로 사용할 수 있으며 대화형 세션에 적합한 간단한 사용법 텍스트로 활용할 수 있습니다. 이후의 문자열 리터럴과 모든 속성 문서 문자열은 Python 바이트코드 컴파일러에서 무시되며 더 상세한 API 정보를 포함할 수 있습니다.

예제:

def function(arg):
    """This is __doc__, function's docstring."""
    """
    This is an additional docstring, ignored by the byte-code
    compiler, but extracted by Docutils.
    """
    pass

독스트링 형식의 선택

모든 사람이 하나의 독스트링 형식을 사용하도록 강제하는 대신, 처리 시스템에서는 여러 입력 형식을 허용합니다. 특수 변수 __docformat__은 함수 또는 클래스 정의보다 앞선 모듈의 최상위 수준에 나타날 수 있습니다. 시간이 지나거나 명령에 따라 표준 형식 또는 형식 집합이 정립되어야 합니다.

모듈의 __docformat__ 변수는 해당 모듈 파일에 정의된 객체에만 적용됩니다. 특히 패키지의 __init__.py 파일에 있는 __docformat__ 변수는 하위 패키지와 하위 모듈에 정의된 객체에는 적용되지 않습니다.

__docformat__ 변수는 사용 중인 형식의 이름을 포함하는 문자열, 입력 파서의 모듈 또는 패키지 이름과 대소문자를 구분하지 않고 일치하는 문자열(즉, 해당 모듈 또는 패키지를 “import”하는 데 필요한 것과 동일한 이름), 또는 등록된 별칭입니다. __docformat__이 지정되지 않은 경우 현재 기본 형식은 “plaintext”이며, 표준 형식이 정립된다면 표준 형식으로 변경될 수 있습니다.

__docformat__ 문자열에는 선택적인 두 번째 필드가 포함될 수 있으며, 이 필드는 형식 이름(첫 번째 필드)과 한 개의 공백으로 구분되는, RFC 1766에 정의된 대소문자를 구분하지 않는 언어 식별자입니다. 일반적인 언어 식별자는 ISO 639에서 정의한 2글자 언어 코드로 구성됩니다(2글자 코드가 존재하지 않는 경우에만 3글자 코드를 사용하며, RFC 1766은 현재 3글자 코드를 허용하도록 개정 중입니다). 언어 식별자가 지정되지 않은 경우 영어의 기본값은 “en”입니다. 언어 식별자는 파서에 전달되며 언어에 종속적인 마크업 기능에 사용될 수 있습니다.

식별자 상호 참조

파이썬 독스트링에서는 변수, 함수, 클래스 및 모듈의 이름과 같은 프로그램 식별자를 분류하고 마크업하기 위해 해석된 텍스트를 사용합니다. 식별자만 제공되면 파이썬 네임스페이스 조회 규칙에 따라 그 역할이 암묵적으로 추론됩니다. 함수와 메서드(동적으로 할당된 경우에도)의 경우 괄호(‘()’)를 포함할 수 있습니다.:

This function uses `another()` to do its work.

클래스, 인스턴스, 모듈 속성에는 필요한 경우 점으로 구분된 식별자를 사용합니다. 예를 들어 (reStructuredText 마크업 사용):

class Keeper(Storer):

    """
    Extend `Storer`.  Class attribute `instances` keeps track
    of the number of `Keeper` objects instantiated.
    """

    instances = 0
    """How many `Keeper` objects are there?"""

    def __init__(self):
        """
        Extend `Storer.__init__()` to keep track of instances.

        Keep count in `Keeper.instances`, data in `self.data`.
        """
        Storer.__init__(self)
        Keeper.instances += 1

        self.data = []
        """Store data in a list, most recent last."""

    def store_data(self, data):
        """
        Extend `Storer.store_data()`; append new `data` to a
        list (in `self.data`).
        """
        self.data = data

백쿼트(“`”)로 인용된 각 식별자는 해당 식별자 자체의 정의를 가리키는 참조가 됩니다.

스타일리스트 변환

스타일리스트 변환은 PySource 리더에 특화된 전용 변환입니다. PySource 리더는 스타일에 관한 어떠한 결정도 내릴 필요가 없습니다. 이는 그저 사용자 정의 노드 타입을 포함하여 파싱되고 링크된, 논리적으로 구성된 문서 트리를 생성할 뿐입니다. 스타일리스트 변환은 리더가 생성한 사용자 정의 노드를 이해하고 이를 표준 Docutils 노드로 변환합니다.

여러 스타일리스트 변환이 구현될 수 있으며, 그중 하나를 실행 시점에 (”–style” 또는 “–stylist” 명령줄 옵션을 통해) 선택할 수 있습니다. 각 스타일리스트 변환은 서로 다른 레이아웃이나 스타일을 구현합니다. 이러한 이유로 이런 이름이 붙었습니다. 이는 리더의 맥락 이해 부분을 처리 과정의 레이아웃 생성 부분과 분리하여, 더 유연하고 견고한 시스템을 만들어냅니다. 이는 또한 SGML/XML의 이상인 “스타일과 내용의 분리”에도 기여합니다.

스타일링을 수행하는 코드 조각을 작고 모듈화된 상태로 유지함으로써, 사용자가 자신만의 스타일을 직접 만드는 일이 훨씬 쉬워집니다. 기존 도구에서는 “진입 장벽”이 너무 높습니다. 스타일리스트 코드를 분리하면 이 장벽이 상당히 낮아질 것입니다.

참조 및 각주

프로젝트 웹 사이트

이 작업을 위한 SourceForge 프로젝트가 http://docutils.sourceforge.net/ 에 설정되어 있습니다.

Acknowledgements

This document borrows ideas from the archives of the Python Doc-SIG. Thanks to all members past & present.