Skip to content
miutePublic

About

Python bindings for ICU4C - ICU for C/C++

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

icupy

PyPI PyPI - Python Version icu PyPI - License pre-commit.ci status tests build wheels

Python bindings for ICU4C using pybind11.

Changes from ICU4C

  • Naming Conventions

    Renamed functions, methods, and enums to conform to PEP 8.

    • Function Names: use lower_case_with_underscores style.
    • Method Names: use lower_case_with_underscores style. Also, use one leading underscore only for protected methods.
    • C++ Enum Member Names: use UPPER_CASE_WITH_UNDERSCORES style without a leading "k". (e.g., kDateOffset → DATE_OFFSET)
    • APIs that match Python reserved words: e.g.,
      • with() → with_()
  • Error Handling

    • ICU C/C++ API errors are raised as icupy.icu.ICUError exceptions. The underlying UErrorCode can be retrieved from the error_code attribute of the exception.

      For example:

      from icupy import icu
      
      try:
          pass  # Call ICU API here...
      except icu.ICUError as e:
          print(e.error_code)  # → icu.ErrorCode
          print(e.error_code.get())  # → icu.UErrorCode

Examples

  • icu::UnicodeString with custom error callback function

    # from Unicode to codepage
    from icupy import icu
    from icupy.utils import gc
    
    
    def from_unicode_cb(
        options: object,
        args: icu.UConverterFromUnicodeArgs,
        code_units: str,
        length: int,
        code_point: int,
        reason: icu.UConverterCallbackReason,
        error_code: icu.ErrorCode,
    ) -> None:
        _ = options, length, code_point  # unused
        if reason in [icu.UCNV_UNASSIGNED, icu.UCNV_ILLEGAL, icu.UCNV_IRREGULAR]:
            error_code.reset()
            source = "".join(f"\\u{ord(c):04x}" for c in code_units)
            icu.ucnv_cb_from_u_write_bytes(args, source, len(source), 0)
    
    
    with gc(icu.ucnv_open("iso8859-1"), icu.ucnv_close) as cnv:
        action = icu.UConverterFromUCallback(from_unicode_cb)
        old_action = icu.ucnv_set_from_u_call_back(cnv, action)
        s = icu.UnicodeString("A€B")
        s.extract(cnv)  # → b'A\\u20acB'
    # from codepage to Unicode
    from icupy import icu
    from icupy.utils import gc
    
    
    def to_unicode_cb(
        options: object,
        args: icu.UConverterToUnicodeArgs,
        code_units: bytes,
        length: int,
        reason: icu.UConverterCallbackReason,
        error_code: icu.ErrorCode,
    ) -> None:
        _ = options, length  # unused
        if reason in [icu.UCNV_UNASSIGNED, icu.UCNV_ILLEGAL, icu.UCNV_IRREGULAR]:
            error_code.reset()
            source = "".join(f"%{b:02X}" for b in code_units)
            icu.ucnv_cb_to_u_write_uchars(args, source, len(source), 0)
    
    
    with gc(icu.ucnv_open("Shift-JIS"), icu.ucnv_close) as cnv:
        action = icu.UConverterToUCallback(to_unicode_cb)
        old_action = icu.ucnv_set_to_u_call_back(cnv, action)
        src = b"\x61\xeb\x40\x62"  # 0xeb 0x40: UNASSIGNED SEQUENCE
        s = icu.UnicodeString(src, -1, cnv)
        str(s)  # → 'a%EB%40b'
  • icu::number::NumberFormatter (ICU 60+)

    from icupy import icu
    from icupy.icu import number
    
    template = (
        number.NumberFormatter.with_()
        .notation(number.Notation.compact_short())
        .unit(icu.CurrencyUnit("EUR"))
        .precision(number.Precision.max_significant_digits(2))
    )
    template.locale("en_US").format_int(1234).to_string()  # "€1.2K" in en-US

Installation

Prerequisites

Installing prerequisites

  • Windows:

    Install the following dependencies:

  • Linux:

    To install dependencies, run the following command:

    • Ubuntu/Debian:

      sudo apt install g++ cmake libicu-dev python3-dev python3-pip
    • Fedora:

      sudo dnf install gcc-c++ cmake icu libicu-devel python3-devel

    Note: If your system's ICU is out of date, consider building ICU4C from source or installing pre-built ICU4C binary package.

Installing icupy

  1. Configuring environment variables

    • Windows:

      • Set the ICU_ROOT environment variable to the root of the ICU installation.

        For example, if the ICU is located in C:\icu4c:

        in PowerShell:

        $env:ICU_ROOT = "C:\icu4c"

        or in Command Prompt:

        set ICU_ROOT=C:\icu4c
      • To verify settings using icuinfo (64-bit):

        in PowerShell:

        & $env:ICU_ROOT\bin64\icuinfo

        or in Command Prompt:

        %ICU_ROOT%\bin64\icuinfo
    • Linux:

      • If the ICU is located in a non-regular place, set the PKG_CONFIG_PATH and LD_LIBRARY_PATH environment variables.

        For example, if the ICU is located in /usr/local:

        export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
        export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
      • To verify settings using pkg-config:

        pkg-config --cflags --libs icu-uc
        # -I/usr/local/include -L/usr/local/lib -licuuc
  2. Installing from PyPI

    pip install icupy

    Optionally, CMake environment variables are available. For example, using the Ninja build system and Clang:

    CMAKE_GENERATOR=Ninja CXX=clang++ pip install icupy

    Alternatively, installing development version from the git repository:

    pip install git+https://github.com/miute/icupy.git

Usage

  1. Configuring environment variables

    • Windows:

      • Set the ICU_ROOT environment variable to the root of the ICU installation (default is C:\icu).

        For example, if the ICU is located in C:\icu4c:

        in PowerShell:

        $env:ICU_ROOT = "C:\icu4c"

        or in Command Prompt:

        set ICU_ROOT=C:\icu4c
    • Linux:

      • If the ICU is located in a non-regular place, set the LD_LIBRARY_PATH environment variables.

        For example, if the ICU is located in /usr/local:

        export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
  2. Using icupy

    from icupy import icu  # or 'import icupy.icu as icu'

License

This project is licensed under the MIT License.

About

Python bindings for ICU4C - ICU for C/C++

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages