from hwpx import ... 최상위 표면은 세 계층으로 나뉩니다. 계층에 따라 계약의
강도와 변경 예고 방식이 다릅니다.
- stable —
hwpx.__all__에 있는 이름. 계약(시그니처·동작·반환 스키마)이 굳어 있고, major 경계에서만 깨질 수 있습니다. 접근 시 경고가 없습니다. - experimental — 계약이 유동적입니다. minor 릴리스에서 변경될 수 있으므로
from hwpx.experimental import ...로 import하세요. 최상위from hwpx import ...경로도 하위 호환을 위해 유지하지만 접근 시DeprecationWarning이 나며, 다음 major에서 최상위 재내보내기가 제거될 예정입니다(실제 구현 모듈·hwpx.experimental경로는 유지). - deprecated — 대체 경로로 이전하세요. 접근 시
DeprecationWarning이 나고 경고 메시지에 대체 경로가 포함됩니다. 다음 major에서 제거될 예정입니다.
이름을 제거하려면 먼저 한 번의 major에서 DeprecationWarning을 낸 뒤 그다음
major에서 제거합니다(경고 없는 즉시 제거 금지). 4.0.0은 이 창을 여는 major였고
제거된 이름이 0개였습니다. 5.0.0은 그 창을 닫는 major로, 4.x에서 경고를 내던
deprecated 표면 4종을 제거합니다(아래 「5.0에서 제거된 deprecated 표면」).
응용 계층으로 옮겨 간 이름은 제거가 아니라 이동이며, import하면 어디로 갔는지
알려 주는 오류가 납니다 — 5.0 마이그레이션 가이드 참조.
5.x 의 이 절은 자기모순이었다. hwpx.oxml.* 을 "공개 표면이 아니다"라고
선언하면서, stable 로 선언한 HwpxDocument 의 메서드들이 HwpxOxmlParagraph·
HwpxOxmlTable·HwpxOxmlSection 등 18종을 반환했다. 사용자는
"비공개"라고 적힌 타입을 손에 쥐고 그것으로 일할 수밖에 없었다.
6.0 은 이렇게 정리한다.
hwpx.model 이 계약이고, hwpx.oxml 은 그것이 사는 곳이다.
from hwpx import model
from hwpx.oxml.paragraph import HwpxOxmlParagraph
assert model.Paragraph is HwpxOxmlParagraph # 래퍼가 아니라 별칭이다래퍼를 만들지 않은 이유: 객체 모델이 두 벌이 되고, 래퍼는 결국 .oxml 을
노출해야 하므로 같은 누출에 코드만 두 배가 된다. 반대로 hwpx.oxml 전체를
stable 로 올리면 24개 모듈 수백 멤버가 major 에서만 바뀔 수 있게 되어, 바로 그
클래스들에 요소를 더해야 하는 포맷 깊이 작업이 멈춘다.
계약은 클래스가 아니라 멤버 목록이다. tests/data/model_surface.json 이
클래스별로 stable 멤버를 정확히 나열한다 — 현재 18개 클래스 / 171개
멤버.
- 목록 안의 멤버 → stable. major 경계에서만 바뀐다.
- 목록 밖의 멤버(79개 —
apply_model·mark_dirty·remove_stale_layout_caches등) → 구현 세부. minor 에서 바뀔 수 있다.
hwpx.oxml.* import 경로는 그대로 살아 있다. 옮기지도, deprecate 하지도 않는다.
hwpx._document.* 등 구현 모듈을 직접 import 하는 것은 공개 표면이 아니다.
hwpx.oxml.* 은 위 규칙을 따른다 — 경로는 열려 있고, 계약은 hwpx.model 의
멤버 목록이 정한다.
HwpxDocument 의 공개 멤버는 34개다(5.x 는 102개). 나머지 79개는 도메인
네임스페이스로 이동했고, 옛 이름은 DeprecationWarning 과 함께 계속 답한다 —
7.0 에서 제거된다. 대응표는 6.0 이주 가이드.
이동은 제거가 아니므로 따로 센다:
| 수 | 락 | |
|---|---|---|
| 루트 공개 멤버 | 34 | tests/data/document_facade_surface.json |
| 위임 shim (7.0 제거) | 79 | tests/data/document_legacy_shims.json |
| 반환 객체 계약 | 171 | tests/data/model_surface.json |
설치본에 직접 물어볼 수도 있다:
python -m hwpx.capabilities --verifymajor 경계에서만 깨지는 이름들입니다.
HwpxDocument,HwpxPackageSavePipeline,QualityPolicy,VisualCompleteReportMutationReport,PreservationDowngradeErrorHwpxError(구조화 예외 베이스 — 아래 오류 계약 참조)EditorOpenSafetyReport,PackageValidationReport,validate_editor_open_safety,validate_package
BytePreservingPatchResult,ParagraphTextPatch,PatchApplied,PatchSkipped,paragraph_patch
TextExtractor,ParagraphInfo,SectionInfo,DEFAULT_NAMESPACESObjectFinder,FoundElementHwpxMarkdownConverter
doc_diff,diff_paragraphs,inspect_reference_consistencymerge_template_rows,load_mail_merge_rows,inspect_mail_merge_placeholdersDOC_DIFF_REPORT_VERSION,REFERENCE_CONSISTENCY_REPORT_VERSION,MAIL_MERGE_REPORT_VERSION
__version__
from hwpx.experimental import ...로 사용하세요. 계약이 유동적입니다.
- 문서 ingestion 프레임워크(임의 포맷 → HWPX):
DocumentIngestor,DocumentConverter,DocumentIngestResult,DocumentSourceInfo,ConversionAttempt,DocumentIngestError,UnsupportedDocumentFormat - 레이아웃 프리뷰(한컴 없는 정직 근사):
render_layout_preview,LayoutPreview,PreviewPage - 문서 프리뷰 뷰어(3.8.0 신규):
render_document_viewer,DocumentViewer - 수식 저작(5.2.0 신규, LaTeX → EqEdit):
latex_to_eqedit,estimate_equation_size,UnsupportedLatexError— 이 세 이름은 5.2.0부터 experimental이었으나 이 문서가 누락하고 있었다 (자기서술 드리프트 —describe_capabilities()의 라이브 census가 이제 이런 누락을 구조적으로 막는다) - 편집 계획 실행기(5.6.0 신규,
hwpx.plan):apply_edit_plan,validate_edit_plan,EditPlan,PlanReport,PlanValidationError - 기계가독 자기서술(5.6.0 신규,
hwpx.capabilities):describe_capabilities,contract_document,contract_json_schema
HwpxMarkdownConverter(HWPX → Markdown 읽기)는 성숙한 경로라 stable입니다. 위 ingestion 프레임워크(임의 포맷 → HWPX)만 experimental입니다.
대체 = 구조적 form-fill 경로(라이브러리 hwpx.table_patch.fill_cells 계열,
MCP analyze_form_fill/apply_form_fill/verify_form_fill).
analyze_template_formfit,apply_template_formfitTEMPLATE_FORMFIT_BASELINE_SCHEMA_VERSION,TEMPLATE_FORMFIT_PLAN_SCHEMA_VERSION
아래 표에 있는 예외 — 쓰기 보존 계약, 저장 경로 게이트, 표 구조 편집, 이동된 표면
안내 — 는 hwpx.errors.HwpxError(최상위 hwpx.HwpxError로도 import) 베이스를
상속합니다. 모든 호출을 감싸는 포괄 계약은 아닙니다: 없는 파일은
FileNotFoundError, HWPX 패키지가 아닌 입력은 zipfile.BadZipFile처럼 파이썬이
원래 내는 예외가 그대로 올라옵니다(지원 매트릭스 참조).
구조화된 예외는 사람용 문장(str(exc))을 그대로 두고, 세 가지 기계가 읽는
필드를 얹습니다:
| 속성 | 의미 |
|---|---|
code |
실패 종류의 안정 식별자(kebab-case). 분기 가능하며 major 경계에서만 바뀜. |
context |
실패를 유발한 실측 값 딕셔너리(오프닝 part·인덱스·개수…). 없으면 {}. |
suggestion |
실행 가능한 다음 한 단계, 없으면 None. |
exc.to_dict()는 {code, message, context, suggestion} 봉투를 돌려줍니다.
구조화 이전에도 각 예외는 ValueError/RuntimeError/Exception이었고, 4.0.0과
5.0.0 모두 그 관계를 유지합니다 — 기존 except가 깨지지 않습니다.
| 예외 | code |
상속 | 발생 경로 |
|---|---|---|---|
PreservationDowngradeError |
preservation-downgrade |
HwpxError |
save_to_path/save_to_stream/to_bytes의 mode="patch" + fallback="error" 미달 |
hwpx.errors.SaveError |
save-failed(기본), document-validation-failed·open-safety-failed·quality-gate-failed |
HwpxError, ValueError |
대표 저장 경로의 사전검증·open-safety·품질 게이트 실패 |
hwpx.table_patch.TableStructureError |
table-structure |
HwpxError, ValueError |
표 구조 편집 거부(fail-closed)·미지원 |
hwpx.table_patch.RenderCheckRequired |
render-check-required |
HwpxError, RuntimeError |
verify_fill(require=True)인데 실한컴 오라클 미렌더 |
응용 계층의 agent·exam 오류 계약은 python-hwpx-automation이 소유합니다.
이 문서는 core에 실제로 남은 공개 예외만 기술합니다.
core가 발행하는 versioned contract(hwpx.mutation-report/v1)는 required 필드
집합이 동결됩니다. document-plan·agent-batch·mixed-form-plan 스키마는 5.0에서
python-hwpx-automation이 발행 주체가 됐으며 그쪽 계약 정책을 따릅니다. 정책·계약 테스트는 스키마 동결을 보세요.