Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5113318
something that is supposed to work but my env does not allow it, seem…
ArthurZucker Jan 12, 2026
c63e47a
?
ArthurZucker Jan 19, 2026
acc9139
up
ArthurZucker Jan 27, 2026
cc21fd7
Merge branch 'more-typehint' of github.com:huggingface/tokenizers int…
ArthurZucker Jan 27, 2026
2c31331
nits
ArthurZucker Jan 27, 2026
a90c4ce
let' s try
ArthurZucker Jan 27, 2026
2f3e416
part of tthe update for pyo3 0.27
ArthurZucker Jan 27, 2026
1546ed2
more pyo3 fixes
ArthurZucker Jan 27, 2026
a1eb245
update
ArthurZucker Jan 27, 2026
affed4c
does this help?
ArthurZucker Jan 27, 2026
c68971c
help
ArthurZucker Jan 27, 2026
098e49d
finally
ArthurZucker Jan 27, 2026
115a1e8
update stub accordingly
ArthurZucker Jan 27, 2026
1315a08
export more of the submodules
ArthurZucker Jan 27, 2026
85691df
moooore
ArthurZucker Jan 27, 2026
8217267
add individual .pypi
ArthurZucker Jan 27, 2026
168601c
cleanup
ArthurZucker Jan 27, 2026
11a9684
update pyo3 signatures and fix warning
ArthurZucker Jan 27, 2026
6a3dd89
style
ArthurZucker Jan 28, 2026
a7b8298
update
ArthurZucker Jan 28, 2026
a326ee1
more updates
ArthurZucker Jan 28, 2026
6c777ba
sytle
ArthurZucker Jan 28, 2026
993af93
clippy happy
ArthurZucker Jan 28, 2026
6ddf491
does this help?
ArthurZucker Jan 28, 2026
63ad9a6
fix
ArthurZucker Jan 30, 2026
062b5f1
fix
ArthurZucker Jan 30, 2026
722186c
?
ArthurZucker Jan 30, 2026
9d47410
what?
ArthurZucker Jan 30, 2026
2b7debd
add dwarwub case co
ArthurZucker Jan 30, 2026
f5e817a
up?
ArthurZucker Jan 30, 2026
ea0c3eb
update
ArthurZucker Jan 30, 2026
700c827
clippy and fmt
ArthurZucker Jan 30, 2026
006cfca
this time it works
ArthurZucker Jan 30, 2026
bd6ebd4
remove offending one
ArthurZucker Jan 30, 2026
55071a9
update
ArthurZucker Jan 30, 2026
2f1805b
remove shit
ArthurZucker Jan 30, 2026
8eee9f6
remove more shit that was unwanted
ArthurZucker Jan 30, 2026
4e22418
?
ArthurZucker Jan 30, 2026
0d1daed
simplify a bit
ArthurZucker Feb 2, 2026
2f77027
more verbose?
ArthurZucker Feb 2, 2026
64f8e9e
more simplification
ArthurZucker Feb 2, 2026
55fe095
fmt
ArthurZucker Feb 2, 2026
354a484
fix some of the typing in rust directly to please TY (but also just f…
ArthurZucker Feb 2, 2026
e089251
fix script running
ArthurZucker Feb 2, 2026
e28c326
fix , ignore and exclude
ArthurZucker Feb 2, 2026
238fe79
style
ArthurZucker Feb 2, 2026
2a8cd2c
update
ArthurZucker Feb 2, 2026
d68785c
fmt + add it to style?
ArthurZucker Feb 2, 2026
ee3a85e
cleanup
ArthurZucker Feb 2, 2026
089f1cd
Simplify stub.py docstring injection
ArthurZucker Feb 3, 2026
dd89cf2
isolate stub generation into separate tools/stub-gen crate
ArthurZucker Feb 6, 2026
2c1ea93
Merge branch 'main' into more-typehint
ArthurZucker Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ jobs:
working-directory: ./bindings/python
run: |
source .env/bin/activate
ty check py_src tests
ty check py_src --exclude py_src/tokenizers/implementations

- name: Run tests
working-directory: ./bindings/python
Expand Down
13 changes: 8 additions & 5 deletions bindings/python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,24 @@ serde = { version = "1.0", features = ["rc", "derive"] }
serde_json = "1.0"
libc = "0.2"
env_logger = "0.11"
pyo3 = { version = "0.26", features = ["abi3", "abi3-py39", "py-clone"] }
pyo3-async-runtimes = { version = "0.26", features = ["tokio-runtime"] }
pyo3 = { version = "0.27.2",default-features = false, features = ["abi3", "abi3-py39", "py-clone", "experimental-inspect"] }
pyo3-async-runtimes = { version = "0.27.0", features = ["tokio-runtime"] }
tokio = { version = "1.47.1", features = ["rt", "rt-multi-thread", "macros", "signal"] }
once_cell = "1.19.0"
numpy = "0.26"
numpy = "0.27"
ndarray = "0.16"
itertools = "0.14"
ahash = { version = "0.8.11", features = ["serde"] }
pyo3-ffi = "0.27.2"

[dependencies.tokenizers]
path = "../../tokenizers"

[dev-dependencies]
tempfile = "3.10"
pyo3 = { version = "0.26", features = ["auto-initialize"] }
pyo3 = { version = "0.27.2", features = ["auto-initialize"] }


[features]
default = ["pyo3/extension-module"]
default = ["ext-module"]
ext-module = ["pyo3/extension-module"]
5 changes: 3 additions & 2 deletions bindings/python/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ check_dirs := examples py_src/tokenizers tests

# Format source code automatically
style:
cargo run --manifest-path tools/stub-gen/Cargo.toml
python stub.py
ruff check $(check_dirs) --fix
ruff format $(check_dirs)
ty check py_src tests
ty check py_src --exclude py_src/tokenizers/implementations

# Check the source code is formatted correctly
check-style:
python stub.py --check
ruff check $(check_dirs)
ruff format --check $(check_dirs)
ty check py_src tests
ty check py_src --exclude py_src/tokenizers/implementations

TESTS_RESOURCES = $(DATA_DIR)/small.txt $(DATA_DIR)/roberta.json

Expand Down
47 changes: 45 additions & 2 deletions bindings/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,49 @@ tokenizer = Tokenizer.from_file("byte-level-bpe.tokenizer.json")
encoded = tokenizer.encode("I can feel the magic, can you?")
```

### Typing support and `stub.py`
### Typing support and stub generation

The compiled PyO3 extension does not expose type annotations, so editors and type checkers would otherwise see most objects as `Any`. The `stub.py` helper walks the loaded extension modules, renders `.pyi` stub files (plus minimal forwarding `__init__.py` shims), and formats them so that tools like mypy/pyright can understand the public API. Run `python stub.py` whenever you change the Python-visible surface to keep the generated stubs in sync.
The compiled PyO3 extension does not expose type annotations, so editors and type checkers would otherwise see most objects as `Any`. To provide full typing support, we use a two-step stub generation process:

1. **Rust introspection** (`tools/stub-gen/`): Uses `pyo3-introspection` to analyze the compiled extension and generate `.pyi` stub files
2. **Python enrichment** (`stub.py`): Adds docstrings from the runtime module and generates forwarding `__init__.py` shims

#### Running stub generation

The easiest way to regenerate stubs is via `make style`:

```bash
cd bindings/python
make style
```

This will:
1. Build the extension with `maturin develop --release`
2. Run introspection to generate `.pyi` files
3. Enrich stubs with docstrings via `stub.py`
4. Format with `ruff`

#### Running manually

To run the stub generator directly:

```bash
cd bindings/python
cargo run --manifest-path tools/stub-gen/Cargo.toml
python stub.py
```

The stub generator automatically:
- Builds the extension using maturin
- Copies the built `.so` to the project root for introspection
- Detects and sets `PYTHONHOME` for embedded Python (handles uv/venv environments)
- Generates stubs to `py_src/tokenizers/`

#### Troubleshooting

If you encounter Python initialization errors, you can manually set `PYTHONHOME`:

```bash
export PYTHONHOME=$(python3 -c 'import sys; print(sys.base_prefix)')
cargo run --manifest-path tools/stub-gen/Cargo.toml
```
2 changes: 1 addition & 1 deletion bindings/python/py_src/tokenizers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class SplitDelimiterBehavior(Enum):
CONTIGUOUS = "contiguous"


from .tokenizers import ( # type: ignore[import]
from .tokenizers import (
AddedToken,
Encoding,
NormalizedString,
Expand Down
Loading
Loading