python-bidi 0.6.10


pip install python-bidi

  Latest version

Released: May 13, 2026


Meta
Author: Meir Kriheli
Requires Python: >=3.9

Classifiers

Development Status
  • 4 - Beta

Intended Audience
  • Developers

Operating System
  • OS Independent

License
  • OSI Approved :: GNU Library or Lesser General Public License (LGPL)

Topic
  • Text Processing

Programming Language
  • Python :: 3
  • Python :: 3.9
  • Python :: 3.10
  • Python :: 3.11
  • Python :: 3.12
  • Python :: 3.13
  • Python :: 3.14

Bi-directional (BiDi) layout for Python providing 2 implementations:

  • V5 of the algorithm implemented with Python.

  • Wrapper the unicode-bidi Rust crate.

Package documentation

For the python implementation, and compatible with previous versions, use:

from bidi.algorithm import get_display

For the newer Rust based one, which seems to implement higher version of the algorithm (albeit with some missing see #25), use the top level import:

from bidi import get_display

API

The algorithm starts with a single entry point get_display (see above for selecting the implementaion).

Required arguments:

  • str_or_bytes: The string or bytes (i.e.: storage). If it’s bytes use the optional argument encoding to specify it’s encoding.

Optional arguments:

  • encoding: If unicode_or_str is a string, specifies the encoding. The algorithm uses unicodedata which requires unicode. This encoding will be used to decode and encode back to string before returning (default: “utf-8”).

  • base_dir: 'L' or 'R', override the calculated base_level.

  • debug: True to display the Unicode levels as seen by the algorithm (default: False).

The Python implementaion adds one more optional argument:

  • upper_is_rtl: True to treat upper case chars as strong ‘R’ for debugging (default: False).

It returns the display layout, either as str or encoding encoded bytes (depending on the type of str_or_bytes').

Example:

>>> from bidi import get_display
>>> # keep as list with char per line to prevent browsers from changing display order
>>> HELLO_HEB = "".join([
...     "ש",
...     "ל",
...     "ו",
...     "ם"
... ])
>>>
>>> HELLO_HEB_DISPLAY = "".join([
...     "ם",
...     "ו",
...     "ל",
...     "ש",
... ])
>>>
>>> get_display(HELLO_HEB) == HELLO_HEB_DISPLAY
True

CLI

pybidi is a command line utility (calling bidi.main) for running the display algorithm. The script can get a string as a parameter or read text from stdin.

Usage:

$ pybidi -h
usage: pybidi [-h] [-e ENCODING] [-u] [-d] [-b {L,R}] [-r] [-v]

options:
-h, --help            show this help message and exit
-e ENCODING, --encoding ENCODING
                        Text encoding (default: utf-8)
-u, --upper-is-rtl    Treat upper case chars as strong 'R' for debugging (default: False), Ignored in Rust algo
-d, --debug           Output to stderr steps taken with the algorithm
-b {L,R}, --base-dir {L,R}
                        Override base direction [L|R]
-r, --rust            Use the Rust unicode-bidi implemention instead of the Python one
-v, --version         show program's version number and exit

Examples:

$ pybidi -u 'Your string here'
$ cat ~/Documents/example.txt | pybidi

Installation

From PyPI:

pip install python-bidi

Or with uv:

uv pip install python-bidi

Development / running tests

You need Rust (for maturin), uv, and a nox session backend of uv (nox reads this from noxfile.py).

From a clone, create the environment and run the test suite:

uv sync --extra dev
uv run pytest

Or use nox (after uv sync --extra dev, or install nox with uv tool install nox / pipx install nox):

nox

Wheel compatibility matrix

Platform CPython 3.8 CPython 3.9 CPython 3.10 CPython 3.11 CPython 3.12 CPython 3.13 CPython 3.14 CPython (additional flags: t) 3.13 CPython (additional flags: t) 3.14 PyPy 3.11 (pp73)
macosx_10_12_x86_64
macosx_11_0_arm64
manylinux1_i686
manylinux2014_aarch64
manylinux2014_armv7l
manylinux2014_ppc64le
manylinux2014_s390x
manylinux2014_x86_64
manylinux_2_17_aarch64
manylinux_2_17_armv7l
manylinux_2_17_ppc64le
manylinux_2_17_s390x
manylinux_2_17_x86_64
manylinux_2_5_i686
musllinux_1_2_aarch64
musllinux_1_2_armv7l
musllinux_1_2_i686
musllinux_1_2_x86_64
win32
win_amd64

Files in release

python_bidi-0.6.10-cp310-cp310-macosx_10_12_x86_64.whl (265.2KiB)
python_bidi-0.6.10-cp310-cp310-macosx_11_0_arm64.whl (264.2KiB)
python_bidi-0.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (289.9KiB)
python_bidi-0.6.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (297.3KiB)
python_bidi-0.6.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (406.8KiB)
python_bidi-0.6.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl (316.2KiB)
python_bidi-0.6.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (294.2KiB)
python_bidi-0.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl (312.7KiB)
python_bidi-0.6.10-cp310-cp310-musllinux_1_2_aarch64.whl (462.6KiB)
python_bidi-0.6.10-cp310-cp310-musllinux_1_2_armv7l.whl (566.7KiB)
python_bidi-0.6.10-cp310-cp310-musllinux_1_2_i686.whl (527.5KiB)
python_bidi-0.6.10-cp310-cp310-musllinux_1_2_x86_64.whl (494.4KiB)
python_bidi-0.6.10-cp310-cp310-win32.whl (158.4KiB)
python_bidi-0.6.10-cp310-cp310-win_amd64.whl (162.4KiB)
python_bidi-0.6.10-cp311-cp311-macosx_10_12_x86_64.whl (265.4KiB)
python_bidi-0.6.10-cp311-cp311-macosx_11_0_arm64.whl (264.2KiB)
python_bidi-0.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (289.9KiB)
python_bidi-0.6.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (297.0KiB)
python_bidi-0.6.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (407.3KiB)
python_bidi-0.6.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl (316.3KiB)
python_bidi-0.6.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (294.1KiB)
python_bidi-0.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl (312.9KiB)
python_bidi-0.6.10-cp311-cp311-musllinux_1_2_aarch64.whl (462.5KiB)
python_bidi-0.6.10-cp311-cp311-musllinux_1_2_armv7l.whl (566.4KiB)
python_bidi-0.6.10-cp311-cp311-musllinux_1_2_i686.whl (527.7KiB)
python_bidi-0.6.10-cp311-cp311-musllinux_1_2_x86_64.whl (494.3KiB)
python_bidi-0.6.10-cp311-cp311-win32.whl (158.0KiB)
python_bidi-0.6.10-cp311-cp311-win_amd64.whl (162.5KiB)
python_bidi-0.6.10-cp312-cp312-macosx_10_12_x86_64.whl (264.2KiB)
python_bidi-0.6.10-cp312-cp312-macosx_11_0_arm64.whl (262.7KiB)
python_bidi-0.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (289.1KiB)
python_bidi-0.6.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (295.4KiB)
python_bidi-0.6.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (406.1KiB)
python_bidi-0.6.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl (315.1KiB)
python_bidi-0.6.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (292.6KiB)
python_bidi-0.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl (310.2KiB)
python_bidi-0.6.10-cp312-cp312-musllinux_1_2_aarch64.whl (461.4KiB)
python_bidi-0.6.10-cp312-cp312-musllinux_1_2_armv7l.whl (564.5KiB)
python_bidi-0.6.10-cp312-cp312-musllinux_1_2_i686.whl (525.7KiB)
python_bidi-0.6.10-cp312-cp312-musllinux_1_2_x86_64.whl (492.9KiB)
python_bidi-0.6.10-cp312-cp312-win32.whl (157.2KiB)
python_bidi-0.6.10-cp312-cp312-win_amd64.whl (161.5KiB)
python_bidi-0.6.10-cp313-cp313-macosx_10_12_x86_64.whl (263.9KiB)
python_bidi-0.6.10-cp313-cp313-macosx_11_0_arm64.whl (262.5KiB)
python_bidi-0.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (289.0KiB)
python_bidi-0.6.10-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (294.9KiB)
python_bidi-0.6.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (406.2KiB)
python_bidi-0.6.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl (315.0KiB)
python_bidi-0.6.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (292.2KiB)
python_bidi-0.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl (309.7KiB)
python_bidi-0.6.10-cp313-cp313-musllinux_1_2_aarch64.whl (461.4KiB)
python_bidi-0.6.10-cp313-cp313-musllinux_1_2_armv7l.whl (564.0KiB)
python_bidi-0.6.10-cp313-cp313-musllinux_1_2_i686.whl (525.1KiB)
python_bidi-0.6.10-cp313-cp313-musllinux_1_2_x86_64.whl (492.6KiB)
python_bidi-0.6.10-cp313-cp313-win32.whl (157.0KiB)
python_bidi-0.6.10-cp313-cp313-win_amd64.whl (161.2KiB)
python_bidi-0.6.10-cp313-cp313t-macosx_10_12_x86_64.whl (263.5KiB)
python_bidi-0.6.10-cp313-cp313t-macosx_11_0_arm64.whl (262.0KiB)
python_bidi-0.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (288.3KiB)
python_bidi-0.6.10-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (294.8KiB)
python_bidi-0.6.10-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (406.0KiB)
python_bidi-0.6.10-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl (314.3KiB)
python_bidi-0.6.10-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (292.5KiB)
python_bidi-0.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl (309.6KiB)
python_bidi-0.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl (460.7KiB)
python_bidi-0.6.10-cp313-cp313t-musllinux_1_2_armv7l.whl (563.9KiB)
python_bidi-0.6.10-cp313-cp313t-musllinux_1_2_i686.whl (525.0KiB)
python_bidi-0.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl (492.3KiB)
python_bidi-0.6.10-cp313-cp313t-win32.whl (156.7KiB)
python_bidi-0.6.10-cp313-cp313t-win_amd64.whl (161.0KiB)
python_bidi-0.6.10-cp314-cp314-macosx_10_12_x86_64.whl (263.9KiB)
python_bidi-0.6.10-cp314-cp314-macosx_11_0_arm64.whl (262.3KiB)
python_bidi-0.6.10-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (288.5KiB)
python_bidi-0.6.10-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (294.8KiB)
python_bidi-0.6.10-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (405.4KiB)
python_bidi-0.6.10-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl (314.8KiB)
python_bidi-0.6.10-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (291.7KiB)
python_bidi-0.6.10-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl (309.5KiB)
python_bidi-0.6.10-cp314-cp314-musllinux_1_2_aarch64.whl (460.9KiB)
python_bidi-0.6.10-cp314-cp314-musllinux_1_2_armv7l.whl (564.1KiB)
python_bidi-0.6.10-cp314-cp314-musllinux_1_2_i686.whl (524.9KiB)
python_bidi-0.6.10-cp314-cp314-musllinux_1_2_x86_64.whl (492.2KiB)
python_bidi-0.6.10-cp314-cp314-win32.whl (157.0KiB)
python_bidi-0.6.10-cp314-cp314-win_amd64.whl (161.2KiB)
python_bidi-0.6.10-cp314-cp314t-macosx_10_12_x86_64.whl (263.3KiB)
python_bidi-0.6.10-cp314-cp314t-macosx_11_0_arm64.whl (261.9KiB)
python_bidi-0.6.10-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (288.1KiB)
python_bidi-0.6.10-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (294.6KiB)
python_bidi-0.6.10-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (405.8KiB)
python_bidi-0.6.10-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl (314.3KiB)
python_bidi-0.6.10-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (292.1KiB)
python_bidi-0.6.10-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl (309.4KiB)
python_bidi-0.6.10-cp314-cp314t-musllinux_1_2_aarch64.whl (460.5KiB)
python_bidi-0.6.10-cp314-cp314t-musllinux_1_2_armv7l.whl (563.6KiB)
python_bidi-0.6.10-cp314-cp314t-musllinux_1_2_i686.whl (524.8KiB)
python_bidi-0.6.10-cp314-cp314t-musllinux_1_2_x86_64.whl (492.1KiB)
python_bidi-0.6.10-cp314-cp314t-win32.whl (156.5KiB)
python_bidi-0.6.10-cp314-cp314t-win_amd64.whl (161.0KiB)
python_bidi-0.6.10-cp38-cp38-macosx_10_12_x86_64.whl (265.3KiB)
python_bidi-0.6.10-cp38-cp38-macosx_11_0_arm64.whl (264.4KiB)
python_bidi-0.6.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (290.1KiB)
python_bidi-0.6.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (297.1KiB)
python_bidi-0.6.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (407.3KiB)
python_bidi-0.6.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl (315.9KiB)
python_bidi-0.6.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (294.3KiB)
python_bidi-0.6.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl (312.3KiB)
python_bidi-0.6.10-cp38-cp38-musllinux_1_2_aarch64.whl (462.8KiB)
python_bidi-0.6.10-cp38-cp38-musllinux_1_2_armv7l.whl (566.4KiB)
python_bidi-0.6.10-cp38-cp38-musllinux_1_2_i686.whl (527.3KiB)
python_bidi-0.6.10-cp38-cp38-musllinux_1_2_x86_64.whl (494.3KiB)
python_bidi-0.6.10-cp38-cp38-win32.whl (158.2KiB)
python_bidi-0.6.10-cp38-cp38-win_amd64.whl (162.3KiB)
python_bidi-0.6.10-cp39-cp39-macosx_10_12_x86_64.whl (265.6KiB)
python_bidi-0.6.10-cp39-cp39-macosx_11_0_arm64.whl (264.6KiB)
python_bidi-0.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (290.6KiB)
python_bidi-0.6.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (297.4KiB)
python_bidi-0.6.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (409.1KiB)
python_bidi-0.6.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl (316.5KiB)
python_bidi-0.6.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (294.4KiB)
python_bidi-0.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl (312.7KiB)
python_bidi-0.6.10-cp39-cp39-musllinux_1_2_aarch64.whl (463.3KiB)
python_bidi-0.6.10-cp39-cp39-musllinux_1_2_armv7l.whl (566.7KiB)
python_bidi-0.6.10-cp39-cp39-musllinux_1_2_i686.whl (527.7KiB)
python_bidi-0.6.10-cp39-cp39-musllinux_1_2_x86_64.whl (494.7KiB)
python_bidi-0.6.10-cp39-cp39-win32.whl (158.3KiB)
python_bidi-0.6.10-cp39-cp39-win_amd64.whl (162.4KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-macosx_10_12_x86_64.whl (267.4KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-macosx_11_0_arm64.whl (266.4KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (292.3KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (298.6KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (410.1KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (317.9KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (295.1KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl (314.9KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl (464.5KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-musllinux_1_2_armv7l.whl (568.1KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-musllinux_1_2_i686.whl (529.2KiB)
python_bidi-0.6.10-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl (496.1KiB)
python_bidi-0.6.10.tar.gz (56.8KiB)
Extras:
Dependencies: