Skip to main content

opencc_pyo3

PyPI version Downloads Python Versions License Build Status

opencc_pyo3 is a Python extension module powered by Rust and PyO3, providing fast and accurate conversion between different Chinese text variants using OpenCC algorithms.

Features

  • Convert between Simplified, Traditional, Hong Kong, Taiwan, and Japanese Kanji variants with OpenCC-compatible configurations.
  • Small Seal Script conversion with s2seal, t2seal, seal2s, and seal2t (added in v0.12.0).
  • High-performance Rust + PyO3 backend for fast, memory-efficient Chinese text conversion in Python.
  • Python API with OpenCC, OpenccConfig, config validation helpers, punctuation conversion, and Chinese text variant detection.
  • Command-line interface for plain text conversion from files or standard input.
  • Office and EPUB document conversion support for .docx, .xlsx, .pptx, .odt, .ods, .odp, and .epub.
  • PDF text extraction helpers, including PDFium-based page-by-page extraction utilities.
  • CJK paragraph reflow helper for cleaning PDF-extracted text before conversion.

Supported Conversion Configurations

  • s2t, t2s, s2tw, tw2s, s2twp, tw2sp, s2hk, hk2s, s2hkp, hk2sp, t2tw, tw2t, t2twp, tw2tp, t2hk, t2hkp, hk2t, hk2tp, t2jp, jp2t, s2seal, t2seal, seal2s, seal2t

Small Seal Script

The four Seal configurations added in v0.12.0 convert between modern Chinese text and Small Seal Script:

Config Conversion
s2seal Simplified Chinese → Small Seal Script
t2seal Traditional Chinese → Small Seal Script
seal2s Small Seal Script → Simplified Chinese
seal2t Small Seal Script → Traditional Chinese

s2seal first converts Simplified to Traditional Chinese. Both forward configurations then bridge modern character variants to regular-script transcriptions and map those transcriptions to Seal characters. Reverse configurations map Seal characters to regular-script transcriptions, bridge them to standard Traditional forms, and, for seal2s, convert those forms to Simplified Chinese. Variant bridging preserves character identity rather than applying historical 本字/假借 substitutions.

from opencc_pyo3 import OpenCC, OpenccConfig

seal = OpenCC(OpenccConfig.S2SEAL).convert("你好,小篆「国际编码18」")
print(seal)  # 你𿒛,𽌠𽴖「𾇓𿭖𿛛碼18」
print(OpenCC("t2seal").convert("你好,小篆「國際編碼18」"))  # Same Seal output
print(OpenCC("seal2s").convert(seal))  # 你好,小篆「国际编码18」
print(OpenCC(OpenccConfig.SEAL2T).convert(seal))  # 你好,小篆「國際編碼18」

Displaying Seal characters requires a font that covers them; conversion still returns Unicode text when the terminal or editor cannot display the glyphs.

Installation

1. Install from PyPI

Install the prebuilt platform-specific wheel:

pip install opencc-pyo3

2. Install directly from GitHub

Install the latest source from the master branch:

pip install "git+https://github.com/laisuk/opencc_pyo3.git@master"

Alternatively, install directly from the GitHub source archive:

pip install "https://github.com/laisuk/opencc_pyo3/archive/refs/heads/master.zip"

The custom PEP 517 build backend automatically bundles the appropriate PDFium native library for the host platform before building the wheel.

Requirements: A working Rust toolchain and Python build environment are required for source installation.

Note: GitHub source installations build against the local system environment and do not apply the compatibility settings used for official release wheels (such as Windows 7 support or Linux manylinux compatibility).

3. Build and install a Python wheel using maturin

For a local build, synchronize the PDFium native library before invoking maturin:

# In the project root
python tools/sync_pdfium_for_wheel.py --local
maturin build --release
pip install ./target/wheels/opencc_pyo3-<version>-cp<pyver>-abi3-<platform>.whl

Or for development (a virtual environment is recommended):

python tools/sync_pdfium_for_wheel.py --local
maturin develop -r

Each platform-specific wheel includes only its matching PDFium native library. PyPI releases provide prebuilt wheels without a source distribution.

See build.txt for detailed build and installation instructions.


Usage

Python

from opencc_pyo3 import OpenCC

text = "“春眠不觉晓,处处闻啼鸟。”"
opencc = OpenCC("s2t")
converted = opencc.convert(text, punctuation=True)
print(converted)  # 「春眠不覺曉,處處聞啼鳥。」

CLI

You can also use the CLI interface via Python module or Python script:
Sub-Commands are:

  • convert: Convert Chinese text using OpenCC
  • office: Convert Office document Chinese text using OpenCC
  • pdf: Convert extracted PDF document text using OpenCC

convert

python -m opencc_pyo3 convert --help
usage: opencc-pyo3 convert [-h] [-i <file>] [-o <file>] [-c <conversion>] [-p] [-n] [-E] [--detofu [<level>]] [--detofu-file <file>] [-D <slot:mode:path>]
                           [--in-enc <encoding>] [--out-enc <encoding>]

optional arguments:
  -h, --help            show this help message and exit
  -i <file>, --input <file>
                        Read original text from <file>. (default: None)
  -o <file>, --output <file>
                        Write converted text to <file>. (default: None)
  -c <conversion>, --config <conversion>
                        Configuration: s2t|s2tw|s2twp|s2hk|s2hkp|t2s|t2tw|t2twp|t2hk|t2hkp|tw2s|tw2sp|tw2t|tw2tp|hk2s|hk2sp|hk2t|hk2tp|jp2t|t2jp|s2seal|t2seal|seal2s|seal2t (default:
                        None)
  -p, --punct           Enable punctuation conversion. (Default: False) (default: False)
  -n, --norm-compat     Normalize CJK Compatibility Ideographs before conversion. (Default: False) (default: False)
  -E, --norm-compat-extended
                        Normalize extended Unicode compatibility forms before conversion. (Default: False) (default: False)
  --detofu [<level>]    Apply tofu-safe fallback after conversion. Levels: all/ExtB, ExtC, ExtD, ExtE, ExtF, ExtG, ExtH, ExtI. (default: None)
  --detofu-file <file>  Load additional detofu fallback mappings from a UTF-8 text file. Custom mappings override built-in mappings; requires --detofu.
                        (default: None)
  -D <slot:mode:path>, --custom-dict <slot:mode:path>
                        Load custom dictionary file. Format: slot:mode:path, e.g. STPhrases:append:custom.txt. Can be used multiple times. Available slots: STC
                        haracters|STPhrases|STPunctuations|TSCharacters|TSPhrases|TSPunctuations|TWPhrases|TWPhrasesRev|HKPhrases|HKPhrasesRev|TWVariants|TWVar
                        iantsPhrases|TWVariantsRev|TWVariantsRevPhrases|HKVariants|HKVariantsPhrases|HKVariantsRev|HKVariantsRevPhrases|JPSCharacters|JPSCharac
                        tersRev|JPSPhrases|SealCharacters|SealCharactersRev|SealVariants|SealVariantsRev (default: None)
  --in-enc <encoding>   Encoding for input. (Default: UTF-8) (default: UTF-8)
  --out-enc <encoding>  Encoding for output files and redirected stdout. Interactive console output uses the terminal's Unicode stream. (Default: UTF-8)
                        (default: UTF-8)

office

Convert Microsoft Office, OpenDocument, and EPUB files (.docx, .xlsx, .pptx, .odt, .ods, .odp, .epub).

Use -F to apply the document's conversion settings to the filename stem when the CLI generates the output path. For example, the following command writes 漢字_converted.docx beside the input file. An explicit --output takes precedence over filename conversion.

opencc-pyo3 office -i "汉字.docx" -c s2t --convert-filename
python -m opencc_pyo3 office --help                                         
usage: opencc-pyo3 office [-h] -i <file> [-o <file>] [-c <conversion>] [-p] [-F] [-n] [-E] [--detofu [<level>]] [--detofu-file <file>] [-f <format>] [-k]        
                          [-D <slot:mode:path>]

optional arguments:
  -h, --help            show this help message and exit
  -i <file>, --input <file>
                        Input Office document from <file>. (default: None)
  -o <file>, --output <file>
                        Output Office document to <file>. (default: None)
  -c <conversion>, --config <conversion>
                        Configuration:
                        s2t|s2tw|s2twp|s2hk|s2hkp|t2s|t2tw|t2twp|t2hk|t2hkp|tw2s|tw2sp|tw2t|tw2tp|hk2s|hk2sp|hk2t|hk2tp|jp2t|t2jp|s2seal|t2seal|seal2s|seal2t
                        (default: None)
  -p, --punct           Enable punctuation conversion. (Default: False) (default: False)
  -F, --convert-filename
                        Convert the input filename stem when generating the default output filename. Ignored when --output is specified. (default: False)
  -n, --norm-compat     Normalize CJK Compatibility Ideographs before conversion. (Default: False) (default: False)
  -E, --norm-compat-extended
                        Normalize extended Unicode compatibility forms before conversion. (Default: False) (default: False)
  --detofu [<level>]    Apply tofu-safe fallback after conversion. Levels: all/ExtB, ExtC, ExtD, ExtE, ExtF, ExtG, ExtH, ExtI. (default: None)
  --detofu-file <file>  Load additional detofu fallback mappings from a UTF-8 text file. Custom mappings override built-in mappings; requires --detofu.
                        (default: None)
  -f <format>, --format <format>
                        Target Office format (e.g., docx, xlsx, pptx, odt, ods, odp, epub) (default: None)
  -k, --keep-font       Preserve font-family information in Office content (default: False)
  -D <slot:mode:path>, --custom-dict <slot:mode:path>
                        Load custom dictionary file. Format: slot:mode:path, e.g. STPhrases:append:custom.txt. Can be used multiple times. Available slots: STC
                        haracters|STPhrases|STPunctuations|TSCharacters|TSPhrases|TSPunctuations|TWPhrases|TWPhrasesRev|HKPhrases|HKPhrasesRev|TWVariants|TWVar
                        iantsPhrases|TWVariantsRev|TWVariantsRevPhrases|HKVariants|HKVariantsPhrases|HKVariantsRev|HKVariantsRevPhrases|JPSCharacters|JPSCharac
                        tersRev|JPSPhrases|SealCharacters|SealCharactersRev|SealVariants|SealVariantsRev (default: None)

PDF

Support PDF files as input, with built-in text extraction and OpenCC-based conversion powered by opencc-fmmseg (available since v0.8.4).

This command allows you to extract Chinese text from PDF documents, optionally apply CJK-aware paragraph reflow, and convert the result using OpenCC configurations.

Note
Only text-embedded (searchable) PDF documents are supported.
Scanned or image-only PDFs without an embedded text layer are not currently supported.

python -m opencc_pyo3 pdf --help
usage: opencc-pyo3 pdf [-h] -i <file> [-o <file>] [-c <conversion>] [-p] [-H] [-r] [-C] [--timing] [-e] [-n] [-E] [--detofu [<level>]] [--detofu-file <file>]
                       [-D <slot:mode:path>]

optional arguments:
  -h, --help            show this help message and exit
  -i <file>, --input <file>
                        Input PDF file. (default: None)
  -o <file>, --output <file>
                        Output text file (UTF-8). If omitted, defaults to "<input>_converted.txt". (default: None)
  -c <conversion>, --config <conversion>
                        Configuration: s2t|s2tw|s2twp|s2hk|s2hkp|t2s|t2tw|t2twp|t2hk|t2hkp|tw2s|tw2sp|tw2t|tw2tp|hk2s|hk2sp|hk2t|hk2tp|jp2t|t2jp|s2seal|t2seal|seal2s|seal2t (default:
                        None)
  -p, --punct           Enable punctuation conversion. (Default: False) (default: False)
  -H, --header          Preserve page-break-like gaps when reflowing CJK paragraphs (passed as add_pdf_page_header to reflow_cjk_paragraphs). (default: False)
  -r, --reflow          Enable CJK-aware paragraph reflow before conversion. (default: False)
  -C, --compact         Use compact paragraph mode (single newline between paragraphs). (default: False)
  --timing              Show time use for each process workflow. (default: False)
  -e, --extract         Extract PDF text only (skip OpenCC conversion). (default: False)
  -n, --norm-compat     Normalize CJK Compatibility Ideographs before conversion. (Default: False) (default: False)
  -E, --norm-compat-extended
                        Normalize extended Unicode compatibility forms before conversion. (Default: False) (default: False)
  --detofu [<level>]    Apply tofu-safe fallback after conversion. Levels: all/ExtB, ExtC, ExtD, ExtE, ExtF, ExtG, ExtH, ExtI. (default: None)
  --detofu-file <file>  Load additional detofu fallback mappings from a UTF-8 text file. Custom mappings override built-in mappings; requires --detofu.
                        (default: None)
  -D <slot:mode:path>, --custom-dict <slot:mode:path>
                        Load custom dictionary file. Format: slot:mode:path, e.g. STPhrases:append:custom.txt. Can be used multiple times. Available slots: STC
                        haracters|STPhrases|STPunctuations|TSCharacters|TSPhrases|TSPunctuations|TWPhrases|TWPhrasesRev|HKPhrases|HKPhrasesRev|TWVariants|TWVar
                        iantsPhrases|TWVariantsRev|TWVariantsRevPhrases|HKVariants|HKVariantsPhrases|HKVariantsRev|HKVariantsRevPhrases|JPSCharacters|JPSCharac
                        tersRev|JPSPhrases|SealCharacters|SealCharactersRev|SealVariants|SealVariantsRev (default: None)
python -m opencc_pyo3 convert -i input.txt -o output.txt -c s2t --punct

python -m opencc_pyo3 convert -i input.txt -o output.txt -c t2s --norm-compat

python -m opencc_pyo3 convert -i input.txt -o output.txt -c s2t --detofu all --detofu-file custom_detofu.txt

echo "這個細路哥很靈活" | python -m opencc_pyo3 convert -c hk2sp --custom-dict HKVariantsRevPhrases:append:my_hk_dict.txt
# output: 这个小男孩很灵活

echo "天龍八部書裡的喬峰是契丹人" | opencc-pyo3 convert -c t2s --norm-compat
# output: 天龙八部书里的乔峰是契丹人
 
python -m opencc_pyo3 office -c s2t --punct -i input.docx -o output.docx --keep-font

opencc-pyo3 office -c s2tw -p -i input.epub -o output.epub

opencc-pyo3 pdf -i input.pdf -o output.txt -c s2t --punct --reflow --norm-compat

opencc-pyo3 convert -i simplified.txt -o seal.txt -c s2seal

opencc-pyo3 convert -i seal.txt -o traditional.txt -c seal2t

opencc-pyo3 convert -i seal.txt -o traditional.txt -c seal2t -D SealCharacters:append:custom_seal.txt

my_hk_dict.txt:

--custom-dict accepts slot:mode:path and can be passed more than once. The token is validated before conversion: slot, mode, and path must all be present. Supported merge modes are append and override; common slots include STPhrases, TWPhrases, HKVariantsRevPhrases, and JPSCharactersRev.

細路哥	小男孩

Python API

OpenccConfig

OpenccConfig is an enum exported from opencc_pyo3 for config-safe usage:

from opencc_pyo3 import OpenCC, OpenccConfig

cc = OpenCC(OpenccConfig.S2TW)
print(cc.convert("汉字"))  # 漢字

Use OpenccConfig.parse("S2TW") to look up a code case-insensitively. Unknown codes raise ValueError. Use to_canonical_name() to get the lowercase code.

Available enum values:

  • OpenccConfig.S2T
  • OpenccConfig.T2S
  • OpenccConfig.S2TW
  • OpenccConfig.TW2S
  • OpenccConfig.S2TWP
  • OpenccConfig.TW2SP
  • OpenccConfig.S2HK
  • OpenccConfig.HK2S
  • OpenccConfig.T2TW
  • OpenccConfig.TW2T
  • OpenccConfig.T2TWP
  • OpenccConfig.TW2TP
  • OpenccConfig.T2HK
  • OpenccConfig.T2HKP
  • OpenccConfig.HK2T
  • OpenccConfig.HK2TP
  • OpenccConfig.T2JP
  • OpenccConfig.JP2T
  • OpenccConfig.S2HKP
  • OpenccConfig.HK2SP
  • OpenccConfig.S2SEAL
  • OpenccConfig.T2SEAL
  • OpenccConfig.SEAL2S
  • OpenccConfig.SEAL2T

OpenCC

Core converter class backed by the Rust extension module.

  • OpenCC(config: str | OpenccConfig = "s2t", preserve_ids: bool = False)
    • config: OpenCC conversion configuration. Codes are case-insensitive. Unknown codes select s2t and set a message in get_last_error().
    • preserve_ids: Preserve characters inside Unicode IDS (Ideographic Description Sequence) structures such as ⿰, ⿱, and ⿲ during conversion. Default is False.
  • OpenCC.from_dicts(config="s2t", specs=None) -> OpenCC
    • Creates a converter with programmatic, in-memory custom dictionary entries.
  • OpenCC.from_dict_files(config="s2t", specs=None) -> OpenCC
    • Creates a converter with OpenCC-style custom dictionary files.
  • convert(input_text: str, punctuation: bool = False) -> str
    • Converts text using the current configuration. Set punctuation=True to apply its punctuation mappings.
  • normalize_compat(text: str) -> str
    • Maps CJK Compatibility Ideographs to their unified forms, such as 金 to 金.
  • normalize_compat_extended(text: str) -> str
    • Applies the CJK ideograph mappings and additional Unicode compatibility mappings. Use either normalization method before convert().
  • detofu(text: str, level: str = "all") -> str
    • Replaces rare CJK extension characters with display-safe fallback characters.
  • detofu_with_custom_file(text: str, level: str = "all", path: str | None = None) -> str
    • Applies DeTofu with additional UTF-8 fallback mappings from a file.
  • detofu_with_custom_pairs(text: str, level: str = "all", pairs: list[tuple[str, str]] | None = None) -> str
    • Applies DeTofu with additional in-memory fallback character pairs.
  • set_config(config: str | OpenccConfig) -> None
    • Changes the active configuration. A valid code clears the configuration error. An unknown code selects s2t and records an error message. The config property and apply_config() provide the same behavior.
  • get_config() -> str
    • Returns the current canonical config name.
  • get_last_error() -> str
    • Returns the most recent config error message, or "" if none.
  • zho_check(input_text: str) -> int
    • Detects the text type.
    • 1 = Traditional Chinese, 2 = Simplified Chinese, 0 = other / undetermined
  • OpenCC.supported_configs() -> list[str]
    • Returns all supported config names.
  • OpenCC.is_valid_config(config: str | OpenccConfig) -> bool
    • Validates a config string.
  • OpenCC.available_slots() -> list[str]
    • Returns all 25 active canonical custom dictionary slot names, including the four Seal slots.

Example:

from opencc_pyo3 import OpenCC, OpenccConfig

cc = OpenCC(OpenccConfig.S2T)
print(cc.get_config())  # s2t
print(cc.convert("汉字", punctuation=True))
print(cc.zho_check("汉字"))  # 2

cc = OpenCC("t2s", preserve_ids=True)
print(cc.convert("漢字 ⿰氵漢 馬"))  # 汉字 ⿰氵漢 马

cc.set_config("t2jp")
print(cc.convert("圖書館"))  # 図書館

# Phrase-aware Traditional ↔ Hong Kong Traditional conversions
print(OpenCC(OpenccConfig.T2HKP).get_config())  # t2hkp
print(OpenCC(OpenccConfig.HK2TP).get_config())  # hk2tp

print(OpenCC.supported_configs())
print(OpenCC.available_slots())
print(OpenCC.is_valid_config("s2hk"))  # True

DeTofu Display Fallbacks

DeTofu can replace rare CJK extension characters with more widely displayable fallback characters after normal OpenCC conversion. The level selects the first extension block to process. "all" starts at ExtB. Use ExtB through ExtI or their short forms B through I. Levels are case-insensitive and accept hyphens or underscores. An unsupported level raises ValueError.

Supply path or pairs for the corresponding custom method, even when using the default level. Each pair contains two single-character strings. Custom mappings take precedence over built-in mappings for the same character.

from opencc_pyo3 import OpenCC

cc = OpenCC("s2t")

print(cc.detofu("𠉂𪠟𫝈𫬐", "all"))
print(cc.detofu_with_custom_file("𣭲毛", "all", "custom_detofu.txt"))
print(cc.detofu_with_custom_pairs("𣭲毛", "all", [("𣭲", "氄")]))

Custom DeTofu files use one mapping per line:

𣭲	氄	B

Custom Dictionaries

Both factories start with the embedded dictionaries and apply custom entries at construction. To change the dictionaries, create a new converter. To switch the active configuration on a factory result, assign cc.config = "t2s" or call cc.apply_config("t2s"). Both factories return the native converter, whose public configuration methods are apply_config() and get_config().

In-memory custom dictionaries

Use OpenCC.from_dicts() for programmatic terms:

from typing import List

from opencc_pyo3 import OpenCC, CustomDictSpec

specs: List[CustomDictSpec] = [
    {
        "slot": "STPhrases",
        "pairs": [("帕兰蒂尔", "柏蘭蒂爾")],
        "mode": "append",
    }
]

cc = OpenCC.from_dicts("s2t", specs)

print(cc.convert("帕兰蒂尔是一家公司"))
# 柏蘭蒂爾是一家公司

File-based custom dictionaries

Use OpenCC.from_dict_files() for OpenCC-style dictionary files:

from typing import List

from opencc_pyo3 import OpenCC, CustomDictFileSpec

specs: List[CustomDictFileSpec] = [
    {
        "slot": "STPhrases",
        "files": ["custom_st_phrases.txt"],
        "mode": "append",
    }
]

cc = OpenCC.from_dict_files("s2t", specs)

Custom dictionary files use one mapping per line:

source<TAB>target

Example:

帕兰蒂尔	柏蘭蒂爾

Merge modes

  • append (default) adds custom entries to the existing dictionary slot. Duplicate keys follow the backend "last wins" behavior.
  • override replaces the entire target dictionary slot with the custom entries or files.

Supported dictionary slots

Use canonical slot names without .txt, such as STPhrases, not STPhrases.txt. The Python wrapper may tolerate .txt, but the documented API uses canonical names only.

Slot Purpose OpenCC dictionary file
STCharacters Simplified → Traditional character mappings STCharacters.txt
STPhrases Simplified → Traditional phrase mappings STPhrases.txt
STPunctuations Simplified → Traditional punctuation mappings STPunctuations.txt
TSCharacters Traditional → Simplified character mappings TSCharacters.txt
TSPhrases Traditional → Simplified phrase mappings TSPhrases.txt
TSPunctuations Traditional → Simplified punctuation mappings TSPunctuations.txt
TWPhrases Traditional → Taiwan phrase mappings TWPhrases.txt
TWPhrasesRev Taiwan → Traditional reverse phrase mappings TWPhrasesRev.txt
HKPhrases Traditional → Hong Kong phrase mappings HKPhrases.txt
HKPhrasesRev Hong Kong → Traditional reverse phrase mappings HKPhrasesRev.txt
TWVariants Traditional → Taiwan regional character variants TWVariants.txt
TWVariantsPhrases Traditional → Taiwan regional phrase variants TWVariantsPhrases.txt
TWVariantsRev Taiwan → Traditional reverse character variants TWVariantsRev.txt
TWVariantsRevPhrases Taiwan → Traditional reverse phrase variants TWVariantsRevPhrases.txt
HKVariants Traditional → Hong Kong regional character variants HKVariants.txt
HKVariantsPhrases Traditional → Hong Kong regional phrase variants HKVariantsPhrases.txt
HKVariantsRev Hong Kong → Traditional reverse character variants HKVariantsRev.txt
HKVariantsRevPhrases Hong Kong → Traditional reverse phrase variants HKVariantsRevPhrases.txt
JPSCharacters Japanese Shinjitai character mappings JPShinjitaiCharacters.txt
JPSCharactersRev Japanese Shinjitai reverse character mappings JPShinjitaiCharactersRev.txt
JPSPhrases Japanese Shinjitai phrase mappings JPShinjitaiPhrases.txt
SealCharacters Small Seal → regular-script transcriptions SealCharacters.txt
SealCharactersRev Regular-script transcriptions → Small Seal SealCharactersRev.txt
SealVariants Modern variants → regular-script transcriptions SealVariants.txt
SealVariantsRev Regular-script transcriptions → standard Traditional SealVariantsRev.txt

Custom dictionary behavior follows the same OpenCC dictionary-slot model. Choosing the wrong slot may have no effect or may affect a different conversion path. For s2t, use STCharacters or STPhrases. For t2s, use TSCharacters or TSPhrases. For Taiwan regional behavior, use TWPhrases, TWPhrasesRev, TWVariantsPhrases, TWVariants, TWVariantsRev, or TWVariantsRevPhrases. For Hong Kong regional behavior, use HKPhrases, HKPhrasesRev, HKVariantsPhrases, HKVariants, HKVariantsRev, or HKVariantsRevPhrases. For Japanese Shinjitai behavior, use JPSCharacters, JPSCharactersRev, or JPSPhrases.

Custom Seal dictionaries

For s2seal and t2seal, use SealVariants for variant bridging and SealCharactersRev for mappings to Seal characters. For seal2s and seal2t, use SealCharacters for mappings from Seal characters and SealVariantsRev for bridging to standard Traditional forms. Each slot is customized separately; changing one does not automatically update its reverse slot. Later conversion stages still apply to custom mapping results.

For example, override the mapping for one Seal character while keeping the rest of the embedded dictionary:

from opencc_pyo3 import OpenCC

cc = OpenCC.from_dicts("seal2t", [{
    "slot": "SealCharacters",
    "mode": "append",
    "pairs": [("𿒛", "佳")],
}])
print(cc.convert("你𿒛"))  # 你佳

The equivalent UTF-8 custom_seal.txt file contains a tab-separated mapping:

𿒛	佳

Use it with OpenCC.from_dict_files("seal2t", [{"slot": "SealCharacters", "mode": "append", "files": ["custom_seal.txt"]}]) or the CLI -D SealCharacters:append:custom_seal.txt example above.

Typing helpers

CustomDictSpec and CustomDictFileSpec are exported for typed Python code:

from typing import List
from opencc_pyo3 import OpenCC, CustomDictSpec

specs: List[CustomDictSpec] = [
    {
        "slot": "STPhrases",
        "pairs": [("帕兰蒂尔", "柏蘭蒂爾")],
        "mode": "append",
    }
]

cc = OpenCC.from_dicts("s2t", specs)

Invalid slots, invalid modes, malformed dictionary lines, and unreadable dictionary files raise ValueError.


Reflow helper

  • reflow_cjk_paragraphs(text: str, add_pdf_page_header: bool, compact: bool) -> str
    • Reflows PDF-extracted CJK text by merging broken line wraps while preserving paragraph structure.
    • add_pdf_page_header=True retains page-like blank-line gaps that reflow would otherwise skip.
    • compact=True uses single newlines between paragraphs. Use False for blank lines.

Example:

from opencc_pyo3.opencc_pyo3 import reflow_cjk_paragraphs

raw_text = "我来到\n无人海边。"
clean_text = reflow_cjk_paragraphs(raw_text, add_pdf_page_header=False, compact=False)  # 我来到无人海边。

PDF extraction APIs

The package exposes PDFium-based PDF extraction helpers in opencc_pyo3.pdfium_helper.

Import from opencc_pyo3.pdfium_helper:

  • extract_pdf_pages_with_callback_pdfium(path: str, callback, /, add_page_header: bool = False) -> None
  • extract_pdf_text_pdfium_progress(path: str) -> str
  • extract_pdf_text_pdfium_silent(path: str) -> str
  • extract_pdf_text_pages_pdfium(path: str, /) -> list[str]
  • extract_pdf_text_pages_pdfium_progress(path: str, /) -> list[str]
  • make_progress_collector() -> tuple[callback, list[str]]
  • make_silent_collector() -> tuple[callback, list[str]]

The callback receives (page_number, total_pages, text) with one-based page numbers. Page text is trimmed and normalized to LF. Blank or unreadable pages contribute separators. Set add_page_header=True to include page markers, or use one of the progress helpers to print extraction progress. PDFium raises a RuntimeError through these helpers if it cannot open the document.

Example:

from opencc_pyo3 import OpenCC
from opencc_pyo3.opencc_pyo3 import reflow_cjk_paragraphs
from opencc_pyo3.pdfium_helper import extract_pdf_text_pdfium_silent

raw = extract_pdf_text_pdfium_silent("input.pdf")
text = reflow_cjk_paragraphs(raw, add_pdf_page_header=False, compact=False)
converted = OpenCC("s2t").convert(text, punctuation=True)

Office and EPUB conversion API

Import convert_office_doc from opencc_pyo3.office_helper to convert a document with a text callback. Pass the format code, such as "docx" or "epub", and a callable that receives a string and returns its replacement. Passing None as the output path creates a sibling file with _converted appended to its stem. The helper validates the resulting archive before replacing an existing output file.

from opencc_pyo3 import OpenCC
from opencc_pyo3.office_helper import convert_office_doc

cc = OpenCC("s2t")
ok, message = convert_office_doc("input.docx", None, "docx", cc.convert, keep_font=True)
print(message)

Development

Benchmarks

Historical benchmark results for opencc-pyo3 v0.10.2, collected by the Benchmark on macos-latest workflow.

Package: opencc_pyo3
Version: 0.10.2
OS: macOS 26.4 (arm64)
CPU: Apple M1 (Virtual)
Cores: 3
Memory: 7.0 GiB
Python: 3.10.11
Rust: rustc 1.97.0 (2d8144b78 2026-07-07)
Configs: s2t, s2tw, s2twp
Text sizes: 100, 1,000, 10,000, 100,000 characters

BENCHMARK RESULTS


Method Config Text Size Mean (ms) Median (ms) StdDev (ms) Min (ms) Max (ms) Ops/sec Chars/sec
Convert_Small s2t 100 0.008 0.005 0.011 0.004 0.071 128,239 12,823,911
Convert_Medium s2t 1,000 0.038 0.037 0.008 0.036 0.108 26,113 26,113,217
Convert_Large s2t 10,000 0.236 0.237 0.030 0.190 0.337 4,229 42,287,025
Convert_XLarge s2t 100,000 2.144 2.088 0.285 1.751 3.034 466 46,638,386
Convert_Small s2tw 100 0.005 0.005 0.001 0.005 0.011 193,679 19,367,928
Convert_Medium s2tw 1,000 0.046 0.043 0.010 0.043 0.133 21,755 21,754,749
Convert_Large s2tw 10,000 0.311 0.309 0.037 0.237 0.424 3,219 32,190,775
Convert_XLarge s2tw 100,000 2.949 2.860 0.445 2.282 4.753 339 33,914,979
Convert_Small s2twp 100 0.006 0.006 0.000 0.005 0.011 177,416 17,741,637
Convert_Medium s2twp 1,000 0.048 0.048 0.002 0.047 0.061 20,783 20,782,517
Convert_Large s2twp 10,000 0.333 0.343 0.037 0.264 0.544 3,002 30,021,166
Convert_XLarge s2twp 100,000 3.034 3.024 0.273 2.497 3.844 330 32,964,999

Summary

For representative Medium through XLarge inputs, s2t is consistently the fastest configuration, reaching about 46.6 million characters per second for the 100,000-character sample. The regional s2tw and phrase-aware s2twp pipelines perform additional dictionary work and reach about 33.9 million and 33.0 million characters per second, respectively, at the same size. Mean and median timings are now close on the larger samples, indicating that full-input warmups and shuffled execution substantially reduced the earlier CI outlier distortion. Results for the 100-character sample should still be treated as microbenchmark-scale measurements, where timer and scheduling noise have a larger relative effect.


Reproduce Benchmarks

python bench/opencc_benchmark_md.py --ci --configs s2t s2tw s2twp --sizes Small Medium Large XLarge --iterations 120 --warmup 15 --warmup-full-text --shuffle-order --export md json --output-dir bench/out

Projects That Use opencc-pyo3

OpenccPyo3Gui


License

MIT


Powered by Rust, PyO3, OpenCC, Pdfium and opencc-fmmseg.

Metadata

Release files for opencc-pyo3 0.12.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for opencc-pyo3 0.12.1
File Actions
opencc_pyo3-0.12.1-cp38-abi3-win_arm64.whl CPython 3.8 abi3 Windows ARM64 Details for opencc_pyo3-0.12.1-cp38-abi3-win_arm64.whl
opencc_pyo3-0.12.1-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details for opencc_pyo3-0.12.1-cp38-abi3-win_amd64.whl
opencc_pyo3-0.12.1-cp38-abi3-win32.whl CPython 3.8 abi3 Windows x86-32 Details for opencc_pyo3-0.12.1-cp38-abi3-win32.whl
opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details for opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details for opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
opencc_pyo3-0.12.1-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details for opencc_pyo3-0.12.1-cp38-abi3-macosx_11_0_arm64.whl
opencc_pyo3-0.12.1-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details for opencc_pyo3-0.12.1-cp38-abi3-macosx_10_12_x86_64.whl

Total release size: 33.1 MB

Release files / opencc_pyo3-0.12.1-cp38-abi3-win_arm64.whl

Download URL opencc_pyo3-0.12.1-cp38-abi3-win_arm64.whl
Size 4.6 MB
Tags CPython 3.8 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
19882586fa72ddeded92f4fddfa85b1a57e6137d78499ffd03a90ad5f7332dbf
BLAKE2b-256 checksum
How to use checksums
0100fd0aaf2d4a5a7ada1f03388a5a41882c48438baa988a8cb41c9f042e634a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / opencc_pyo3-0.12.1-cp38-abi3-win_amd64.whl

Download URL opencc_pyo3-0.12.1-cp38-abi3-win_amd64.whl
Size 4.8 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
e0db25de02487b3eb4915b5a898ff9d2527a82032595503d12e8b0031ee2a4fa
BLAKE2b-256 checksum
How to use checksums
a117841ea77ac7498d1fd7221d9d594465ad09efffaa5b75b1dc73a48e753d8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / opencc_pyo3-0.12.1-cp38-abi3-win32.whl

Download URL opencc_pyo3-0.12.1-cp38-abi3-win32.whl
Size 4.6 MB
Tags CPython 3.8 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
ab787932caaa2adba088fda1f92a1a7eb53a9d3d2c4c1babd27b433dd00a7359
BLAKE2b-256 checksum
How to use checksums
8c5b6b754f3f893e01aa52b21b7b8a342365e7c692b2b9255126404527783b4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 4.9 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
36e1ae9b7696bbf8d356d1fd0a0a3ec3b30541ad92728742475b46c5b1bd3e12
BLAKE2b-256 checksum
How to use checksums
bc764ae9d02a2dc3b2eba9af83240aabc6ae5e8f6c9e89ddc4cd6ecbf11791e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL opencc_pyo3-0.12.1-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 4.9 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
b4888bc33973dbdf0ec86ff190baf5a26fc69e5d749f36a9d74e9cdc3f06f83a
BLAKE2b-256 checksum
How to use checksums
66a24e0bc82f0d72fe12130e9cad68889c4d25894482d3c0ef684a40b6f66714
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / opencc_pyo3-0.12.1-cp38-abi3-macosx_11_0_arm64.whl

Download URL opencc_pyo3-0.12.1-cp38-abi3-macosx_11_0_arm64.whl
Size 4.6 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
44a85c6097f3068c057b2cf2947ba374a6677db1dd6597f1cf836c558bb00e74
BLAKE2b-256 checksum
How to use checksums
98c35e94b6c6244713e2d43ce4c5bc82cfc5cda9a72e9bd3aa4a7e6e4b6c7aac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / opencc_pyo3-0.12.1-cp38-abi3-macosx_10_12_x86_64.whl

Download URL opencc_pyo3-0.12.1-cp38-abi3-macosx_10_12_x86_64.whl
Size 4.7 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
e8caa00a40471f73a200e9c1c53ac2220f22e2df9217af99598966b2ae08a5c4
BLAKE2b-256 checksum
How to use checksums
0221961122c34d5ae1f46dba2c89522d71af7ae095ffb4ab7aa2d11cd8627ccb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for opencc-pyo3 0.12.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page