python-bidi 0.6.7


pip install python-bidi

  Latest version

Released: Oct 22, 2025


Meta
Author: Meir Kriheli

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

At the command line (assuming you’re using some virtualenv):

pip install python-bidi

Running tests

To run the tests:

pip 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 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.7-cp310-cp310-macosx_10_12_x86_64.whl (268.4KiB)
python_bidi-0.6.7-cp310-cp310-macosx_11_0_arm64.whl (258.5KiB)
python_bidi-0.6.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (286.8KiB)
python_bidi-0.6.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (295.5KiB)
python_bidi-0.6.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (430.8KiB)
python_bidi-0.6.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl (319.1KiB)
python_bidi-0.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (295.0KiB)
python_bidi-0.6.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl (308.1KiB)
python_bidi-0.6.7-cp310-cp310-musllinux_1_2_aarch64.whl (462.9KiB)
python_bidi-0.6.7-cp310-cp310-musllinux_1_2_armv7l.whl (553.8KiB)
python_bidi-0.6.7-cp310-cp310-musllinux_1_2_i686.whl (482.2KiB)
python_bidi-0.6.7-cp310-cp310-musllinux_1_2_x86_64.whl (454.3KiB)
python_bidi-0.6.7-cp310-cp310-win32.whl (153.7KiB)
python_bidi-0.6.7-cp310-cp310-win_amd64.whl (157.3KiB)
python_bidi-0.6.7-cp311-cp311-macosx_10_12_x86_64.whl (268.0KiB)
python_bidi-0.6.7-cp311-cp311-macosx_11_0_arm64.whl (258.4KiB)
python_bidi-0.6.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (286.8KiB)
python_bidi-0.6.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (295.5KiB)
python_bidi-0.6.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (431.3KiB)
python_bidi-0.6.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl (319.3KiB)
python_bidi-0.6.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (295.0KiB)
python_bidi-0.6.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl (308.3KiB)
python_bidi-0.6.7-cp311-cp311-musllinux_1_2_aarch64.whl (462.9KiB)
python_bidi-0.6.7-cp311-cp311-musllinux_1_2_armv7l.whl (553.7KiB)
python_bidi-0.6.7-cp311-cp311-musllinux_1_2_i686.whl (482.4KiB)
python_bidi-0.6.7-cp311-cp311-musllinux_1_2_x86_64.whl (454.3KiB)
python_bidi-0.6.7-cp311-cp311-win32.whl (153.4KiB)
python_bidi-0.6.7-cp311-cp311-win_amd64.whl (157.5KiB)
python_bidi-0.6.7-cp312-cp312-macosx_10_12_x86_64.whl (266.1KiB)
python_bidi-0.6.7-cp312-cp312-macosx_11_0_arm64.whl (257.1KiB)
python_bidi-0.6.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (285.8KiB)
python_bidi-0.6.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (293.8KiB)
python_bidi-0.6.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (428.8KiB)
python_bidi-0.6.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl (318.2KiB)
python_bidi-0.6.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (293.5KiB)
python_bidi-0.6.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl (305.7KiB)
python_bidi-0.6.7-cp312-cp312-musllinux_1_2_aarch64.whl (461.7KiB)
python_bidi-0.6.7-cp312-cp312-musllinux_1_2_armv7l.whl (552.0KiB)
python_bidi-0.6.7-cp312-cp312-musllinux_1_2_i686.whl (480.3KiB)
python_bidi-0.6.7-cp312-cp312-musllinux_1_2_x86_64.whl (452.9KiB)
python_bidi-0.6.7-cp312-cp312-win32.whl (152.2KiB)
python_bidi-0.6.7-cp312-cp312-win_amd64.whl (156.2KiB)
python_bidi-0.6.7-cp313-cp313-macosx_10_12_x86_64.whl (265.8KiB)
python_bidi-0.6.7-cp313-cp313-macosx_11_0_arm64.whl (257.0KiB)
python_bidi-0.6.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (285.6KiB)
python_bidi-0.6.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (293.7KiB)
python_bidi-0.6.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (428.5KiB)
python_bidi-0.6.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl (318.1KiB)
python_bidi-0.6.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (293.5KiB)
python_bidi-0.6.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl (305.6KiB)
python_bidi-0.6.7-cp313-cp313-musllinux_1_2_aarch64.whl (461.7KiB)
python_bidi-0.6.7-cp313-cp313-musllinux_1_2_armv7l.whl (551.7KiB)
python_bidi-0.6.7-cp313-cp313-musllinux_1_2_i686.whl (480.2KiB)
python_bidi-0.6.7-cp313-cp313-musllinux_1_2_x86_64.whl (452.7KiB)
python_bidi-0.6.7-cp313-cp313-win32.whl (152.1KiB)
python_bidi-0.6.7-cp313-cp313-win_amd64.whl (156.1KiB)
python_bidi-0.6.7-cp314-cp314-macosx_10_12_x86_64.whl (265.5KiB)
python_bidi-0.6.7-cp314-cp314-macosx_11_0_arm64.whl (256.1KiB)
python_bidi-0.6.7-cp314-cp314-musllinux_1_2_aarch64.whl (460.9KiB)
python_bidi-0.6.7-cp314-cp314-musllinux_1_2_armv7l.whl (551.8KiB)
python_bidi-0.6.7-cp314-cp314-musllinux_1_2_i686.whl (479.7KiB)
python_bidi-0.6.7-cp314-cp314-musllinux_1_2_x86_64.whl (452.3KiB)
python_bidi-0.6.7-cp314-cp314-win32.whl (152.1KiB)
python_bidi-0.6.7-cp314-cp314-win_amd64.whl (156.1KiB)
python_bidi-0.6.7-cp38-cp38-macosx_10_12_x86_64.whl (268.0KiB)
python_bidi-0.6.7-cp38-cp38-macosx_11_0_arm64.whl (258.6KiB)
python_bidi-0.6.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (286.9KiB)
python_bidi-0.6.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (295.4KiB)
python_bidi-0.6.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (430.1KiB)
python_bidi-0.6.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl (319.3KiB)
python_bidi-0.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (294.7KiB)
python_bidi-0.6.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl (308.2KiB)
python_bidi-0.6.7-cp38-cp38-musllinux_1_2_aarch64.whl (463.1KiB)
python_bidi-0.6.7-cp38-cp38-musllinux_1_2_armv7l.whl (553.7KiB)
python_bidi-0.6.7-cp38-cp38-musllinux_1_2_i686.whl (482.2KiB)
python_bidi-0.6.7-cp38-cp38-musllinux_1_2_x86_64.whl (453.8KiB)
python_bidi-0.6.7-cp38-cp38-win32.whl (153.6KiB)
python_bidi-0.6.7-cp38-cp38-win_amd64.whl (157.3KiB)
python_bidi-0.6.7-cp39-cp39-macosx_10_12_x86_64.whl (268.3KiB)
python_bidi-0.6.7-cp39-cp39-macosx_11_0_arm64.whl (258.6KiB)
python_bidi-0.6.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (287.0KiB)
python_bidi-0.6.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (295.5KiB)
python_bidi-0.6.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (430.6KiB)
python_bidi-0.6.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl (319.3KiB)
python_bidi-0.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (295.1KiB)
python_bidi-0.6.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl (308.2KiB)
python_bidi-0.6.7-cp39-cp39-musllinux_1_2_aarch64.whl (463.0KiB)
python_bidi-0.6.7-cp39-cp39-musllinux_1_2_armv7l.whl (553.8KiB)
python_bidi-0.6.7-cp39-cp39-musllinux_1_2_i686.whl (482.3KiB)
python_bidi-0.6.7-cp39-cp39-musllinux_1_2_x86_64.whl (454.1KiB)
python_bidi-0.6.7-cp39-cp39-win32.whl (153.7KiB)
python_bidi-0.6.7-cp39-cp39-win_amd64.whl (157.2KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-macosx_10_12_x86_64.whl (269.8KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl (260.7KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (288.8KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (297.0KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (432.1KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (321.4KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (296.4KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl (310.3KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl (464.9KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-musllinux_1_2_armv7l.whl (555.0KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-musllinux_1_2_i686.whl (483.7KiB)
python_bidi-0.6.7-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl (456.2KiB)
python_bidi-0.6.7.tar.gz (44.4KiB)
Extras:
Dependencies: