TurboText
Lightning-fast, boundary-aware keyword matching for Python
Exact · Fuzzy · Multi-word · Unicode · Pluggable conflict resolution
TurboText finds keywords in text the way a human editor would — enforcing real word boundaries, tolerating typos, handling multi-word phrases, and letting you declare which match wins when keywords overlap, including an optimal (not just greedy) weighted resolver that no other keyword library provides.
Table of Contents
- Why TurboText?
- Features
- Installation
- Quick Start
- Adding Keywords
- Extracting Matches
- Replacing Keywords
- Fuzzy Matching
- Conflict Resolution Policies
- Per-Keyword Metadata
- Word Boundary Rules
- Performance
- API Reference
- Development
- Author
- License
Why TurboText?
re |
FlashText | RapidFuzz | TurboText | |
|---|---|---|---|---|
| Exact keyword extraction | ✅ | ✅ | ❌ | ✅ |
| Fuzzy / typo-tolerant | ❌ | ❌ | ✅ | ✅ |
| Word boundary enforcement | ✅ | ✅ | ❌ | ✅ |
| Extracts spans from running text | ✅ | ✅ | ❌ | ✅ |
| Multi-word phrases (native) | ✅ | ✅ | ⚠️ | ✅ |
| O(text) scaling with vocab | ❌ | ✅ | ❌ | ✅ |
| Per-keyword metadata | ❌ | ❌ | ❌ | ✅ |
| Conflict resolution policies | ❌ | ❌ | ❌ | ✅ |
| Optimal weighted resolution | ❌ | ❌ | ❌ | ✅ |
Features
- Exact matching — trie-based O(n) scan, constant in vocabulary size
- Fuzzy matching — Levenshtein distance up to k via bounded-edit frontier search
- Word boundary enforcement — Unicode-correct; matches
catbut notcats,scat, orconcatenate - Multi-word keywords —
"new york","product manager"work out of the box - Bulk loading — accepts
list,dict[str, str], ordict[str, list[str]] - Five conflict policies —
ALL_OVERLAPS,LEFTMOST_LONGEST,LEFTMOST_FIRST,HIGHEST_PRIORITY,OPTIMAL_WEIGHTED - Optimal resolution — O(n log n) weighted interval scheduling DP — picks the globally best non-overlapping set
- Rich match objects — canonical form, offsets, edit distance, category, priority, custom metadata
- Cython fast-path — compiled extension ships with every wheel; packed transition-table automaton, 1.5× faster than FlashText on 1 M-word corpora
Installation
pip install turbotext
The Cython extension is built automatically when installing from PyPI (wheels are pre-compiled for CPython 3.10–3.13 on Linux, macOS, and Windows). No extra steps needed.
TurboText falls back to pure Python automatically if the compiled extension is unavailable (e.g. unsupported platform or source install without a C compiler).
Install with uv (development)
git clone https://github.com/nishankmahore/TurboText
cd TurboText
uv sync --group dev
python setup.py build_ext --inplace
Quick Start
from turbotext import KeywordStore, MatchPolicy, FuzzyConfig
store = KeywordStore(
policy=MatchPolicy.LEFTMOST_LONGEST,
fuzzy=FuzzyConfig(max_edit_distance=1),
)
store.add_keywords({
"aspirin": ["aspirin", "asprin", "aspirin tablet"],
"ibuprofen": ["ibuprofen", "ibuprofen tablet"],
})
text = "Patient takes asprin and ibuprofen tablet daily"
for m in store.extract(text):
print(f"{m.canonical:12} ed={m.edit_distance} [{m.start}:{m.end}] '{m.text}'")
# aspirin ed=1 [14:20] 'asprin'
# ibuprofen ed=0 [25:42] 'ibuprofen tablet'
print(store.replace(text))
# Patient takes aspirin and ibuprofen daily
Adding Keywords
Single keyword
store = KeywordStore()
# minimal — surface form becomes the canonical
store.add_keyword("aspirin")
# with canonical form
store.add_keyword("aspirin", canonical="Aspirin")
# with full metadata
kid = store.add_keyword(
"aspirin",
canonical="Aspirin",
category="DRUG",
priority=10.0,
rxnorm_code="1191", # any extra kwargs become metadata
source="rxnorm",
)
print(kid) # "3f4a2b1c-..." UUID — useful for tracking
From a list
store.add_keywords(["java", "python", "rust"])
# surface form = canonical for each entry
From a {surface: canonical} dict
store.add_keywords({
"py": "Python",
"js": "JavaScript",
"k8s": "Kubernetes",
})
From a {canonical: [surfaces]} dict (most common bulk shape)
keyword_dict = {
"java": ["java", "java_2e", "java programing"],
"product management": ["PM", "product manager", "prod mgmt"],
"machine learning": ["ML", "machine learning", "deep learning"],
}
store.add_keywords(keyword_dict)
Mixed dict
String values follow {surface: canonical}; list values follow {canonical: [surfaces]}.
store.add_keywords({
"java": ["java_2e", "java programing"], # canonical → [surfaces]
"py": "Python", # surface → canonical
})
Shared category and priority
store.add_keywords(
{
"aspirin": ["aspirin", "asprin"],
"ibuprofen": ["ibuprofen", "advil"],
},
category="DRUG",
priority=5.0,
)
Extracting Matches
matches = store.extract("take aspirin and ibuprofen daily")
for m in matches:
print(m.text) # surface text found in the input
print(m.canonical) # normalised keyword name
print(m.start, m.end) # character offsets — text[m.start:m.end]
print(m.edit_distance) # 0 = exact, 1 = one typo, etc.
print(m.category) # "DRUG"
print(m.priority) # 10.0
print(m.keyword_id) # UUID string
print(m.metadata) # {"rxnorm_code": "1191", ...}
Match uses __slots__ for fast bulk creation — all fields are fixed and the object is lightweight.
Replacing Keywords
store = KeywordStore()
store.add_keywords({
"aspirin": "Aspirin",
"tylenol": "Acetaminophen", # alias → same canonical
"ibuprofen": "Ibuprofen",
})
print(store.replace("take aspirin or tylenol twice daily"))
# take Aspirin or Acetaminophen twice daily
Fuzzy Matching
from turbotext import FuzzyConfig
store = KeywordStore(fuzzy=FuzzyConfig(max_edit_distance=1))
store.add_keyword("aspirin")
store.extract("take asprin") # substitution i → r ✅
store.extract("take aspirn") # deletion missing i ✅
store.extract("take aspirrin") # insertion extra r ✅
Boundary enforcement still applies
store.extract("I see cbt") # ✅ whole word
store.extract("I see xcbt") # ❌ left boundary fails
store.extract("I see cbts") # ❌ right boundary fails
Choosing max_edit_distance
| Value | Use case |
|---|---|
0 |
Exact matching only (default) — uses Cython fast-path when available |
1 |
Single-character typos — medical terms, product names — uses Cython fast-path when available |
2 |
Two-character errors — longer technical terms — uses Cython fast-path when available |
Higher values increase recall but also false positives. Start with
1and tune.
Conflict Resolution Policies
When keywords overlap, the policy decides which match to keep.
ALL_OVERLAPS — return everything, you decide
store = KeywordStore(policy=MatchPolicy.ALL_OVERLAPS)
store.add_keywords(["new", "new york", "york"])
store.extract("new york")
# → ["new", "new york", "york"]
LEFTMOST_LONGEST (default) — FlashText-compatible greedy
store = KeywordStore(policy=MatchPolicy.LEFTMOST_LONGEST)
store.add_keywords(["new", "new york"])
store.extract("new york")
# → ["new york"] longest match wins
LEFTMOST_FIRST — earliest start wins
store = KeywordStore(policy=MatchPolicy.LEFTMOST_FIRST)
store.add_keywords(["new", "new york"])
store.extract("new york")
# → ["new"] first token wins
HIGHEST_PRIORITY — priority-based greedy
store = KeywordStore(policy=MatchPolicy.HIGHEST_PRIORITY)
store.add_keyword("new york", canonical="New York", priority=2.0)
store.add_keyword("york", canonical="York", priority=5.0)
store.add_keyword("new", canonical="New", priority=1.0)
store.extract("new york")
# → ["New", "York"] priority 5 beats priority 2; "new" doesn't overlap "york"
OPTIMAL_WEIGHTED — globally optimal, not greedy
store = KeywordStore(policy=MatchPolicy.OPTIMAL_WEIGHTED)
store.add_keyword("ab cd", canonical="LONG", priority=5.0)
store.add_keyword("ab", canonical="SHORT1", priority=3.0)
store.add_keyword("cd", canonical="SHORT2", priority=3.0)
store.extract("ab cd")
# Greedy picks "LONG" (5). Optimal picks "SHORT1"+"SHORT2" (3+3=6).
# → ["SHORT1", "SHORT2"]
Per-Keyword Metadata
store.add_keyword(
"aspirin",
canonical="Aspirin",
category="DRUG",
priority=10.0,
rxnorm_code="1191",
source="rxnorm",
approved=True,
)
m = store.extract("take aspirin")[0]
print(m.canonical) # "Aspirin"
print(m.category) # "DRUG"
print(m.priority) # 10.0
print(m.metadata["rxnorm_code"]) # "1191"
Match.metadata is a shallow copy — mutating it does not affect the stored keyword.
Word Boundary Rules
TurboText uses Unicode word boundaries — word characters are [a-zA-Z0-9_] and their Unicode equivalents.
store.add_keyword("cat")
# ✅ Accepted
store.extract("cat") # text edge
store.extract("the cat sat") # spaces
store.extract("(cat)") # punctuation
store.extract("cat, sat") # comma
# ❌ Rejected
store.extract("cats") # right boundary fails
store.extract("scat") # left boundary fails
store.extract("cat2") # digit is a word char
store.extract("concatenate") # substring
Performance
Apple M-series · best-of-3 runs · Cython extension enabled
1 M-word throughput (1,000 keywords, 7.8 MB corpus)
TurboText's Aho-Corasick engine with inline lowercasing and zero-copy resolve beats FlashText on large documents.
| Library | Time (s) | Matches | vs FlashText |
|---|---|---|---|
| TurboText (k=0) | 0.54 | ~500,000 | 1.5× faster |
| FlashText | 0.79 | ~500,000 | baseline |
Exact matching vs regex — vocabulary scaling (k=0)
TurboText is O(text) — scan time is flat as vocabulary grows. re alternation degrades linearly with term count because every disjunct is tried at every position.
The k=0 engine is a packed transition table: the Aho-Corasick automaton is flattened into one contiguous int32 array (state*128+char → next_state) instead of a graph of individually heap-allocated trie nodes. Transitions become a single branchless array index — no null-check, no pointer chase through separate node/list/array allocations — so the win grows with automaton size as more of the old pointer graph would have spilled out of cache.
| Library | 100 terms | 1,000 terms | 5,000 terms | 20,000 terms | Complexity |
|---|---|---|---|---|---|
| TurboText | 1.2 ms | 1.3 ms | 1.4 ms | 1.6 ms | O(text) |
re |
4.8 ms | 40.1 ms | 213.3 ms | 846.1 ms | O(text × vocab) |
Exact matching vs the Aho-Corasick family (k=0)
Separated from the regex comparison above because it's a different question: every library here is already O(text), so the story isn't complexity class, it's implementation constants — Python-object overhead, boundary handling, and (for the C extension) FFI/allocation cost. pyahocorasick's C core wins on raw scan speed but hands back plain substring spans with no boundary awareness or multi-word phrase support — it's a general-purpose multi-pattern search primitive, not a keyword-extraction library.
TurboText (spans) is extract_spans(): the same FlatAC engine as extract(), but returning bare (start, end, keyword_id) tuples instead of building a Match object per hit (no text-slice, no attribute assignment, no metadata dict). Keyword refs are int-indexed internally (an array lookup) rather than hashed by a 36-char uuid string, so this is close to pyahocorasick's raw-scan speed while still being boundary-aware. extract() pays the difference for Match objects — canonical form, category, priority, metadata — which pyahocorasick doesn't have a concept of at all.
| Library | 100 terms | 1,000 terms | 5,000 terms | 20,000 terms | Boundary-aware |
|---|---|---|---|---|---|
| TurboText | 1.2 ms | 1.3 ms | 1.3 ms | 1.5 ms | ✅ |
| TurboText (spans) | 0.5 ms | 0.5 ms | 0.6 ms | 0.7 ms | ✅ |
| FlashText | 2.9 ms | 3.0 ms | 3.1 ms | 3.2 ms | ✅ |
| flashtext2 | 1.1 ms | 1.1 ms | 1.1 ms | 1.1 ms | ✅ |
| pyahocorasick | 0.4 ms | 0.6 ms | 0.6 ms | 0.7 ms | ❌ |
Fuzzy matching vs FuzzyWuzzy — vocabulary scaling (k=1)
TurboText's fuzzy path (bounded-edit frontier search) is a Cython fast path, same as exact matching: a single-pass trie scan regardless of vocabulary size. FuzzyWuzzy tokenises the text and scores every token against every keyword with a pure-Python-Levenshtein-backed ratio — O(tokens × vocab), and it shows: 5,000 keywords take over 11 seconds.
| Library | 100 terms | 500 terms | 1,000 terms | 2,000 terms | 5,000 terms |
|---|---|---|---|---|---|
| TurboText | 18 ms | 32 ms | 48 ms | 56 ms | 70 ms |
| FuzzyWuzzy | 222 ms | 1,098 ms | 2,231 ms | 4,398 ms | 11,394 ms |
Fuzzy matching vs RapidFuzz, python-Levenshtein, jellyfish (k=1)
A separate chart because these three don't share FuzzyWuzzy's story: RapidFuzz has a genuinely C-accelerated batch primitive (process.extractOne), while python-Levenshtein and jellyfish only expose a single-pair distance function — no batch "find the best match in this list" API — so a token × keyword nested loop calling their distance function is the realistic way to use them here, not an artificial handicap. That nested loop puts jellyfish in the same ballpark as FuzzyWuzzy above (11.1s vs 11.4s at 5,000 terms) despite jellyfish's distance function itself being fast in isolation.
| Library | 100 terms | 500 terms | 1,000 terms | 2,000 terms | 5,000 terms | Boundary-aware | Extracts spans |
|---|---|---|---|---|---|---|---|
| TurboText | 18 ms | 32 ms | 44 ms | 55 ms | 69 ms | ✅ | ✅ |
| RapidFuzz | 13 ms | 62 ms | 121 ms | 244 ms | 608 ms | ❌ | ❌ |
| python-Levenshtein | 58 ms | 290 ms | 576 ms | 1,157 ms | 2,879 ms | ❌ | ❌ |
| jellyfish | 224 ms | 1,130 ms | 2,220 ms | 4,471 ms | 11,127 ms | ❌ | ❌ |
TurboText overtakes RapidFuzz at ~500 keywords and is 8.8× faster at 5,000 terms. Unlike RapidFuzz (a string scorer used with process.extractOne per token), TurboText returns character offsets, enforces word boundaries, and handles multi-word phrases natively — and unlike python-Levenshtein/jellyfish, it never needs an O(tokens × vocab) nested loop in the first place.
API Reference
KeywordStore(policy, fuzzy)
store = KeywordStore(
policy=MatchPolicy.LEFTMOST_LONGEST, # default
fuzzy=FuzzyConfig(max_edit_distance=0), # default — exact only
)
| Parameter | Type | Default | Description |
|---|---|---|---|
policy |
MatchPolicy |
LEFTMOST_LONGEST |
Conflict-resolution strategy |
fuzzy |
FuzzyConfig | None |
None |
Fuzzy config; None = exact only |
add_keyword(surface_form, *, canonical, category, priority, **metadata) → str
kid = store.add_keyword(
"aspirin",
canonical="Aspirin",
category="DRUG",
priority=10.0,
rxnorm_code="1191",
)
| Parameter | Type | Default | Description |
|---|---|---|---|
surface_form |
str |
required | Text to search for |
canonical |
str |
surface_form |
Normalised name returned on match |
category |
str | None |
None |
Grouping label |
priority |
float |
1.0 |
Weight for priority-based policies |
**metadata |
Any |
— | Arbitrary extra fields |
Returns the keyword's UUID string.
add_keywords(keywords, *, category, priority) → list[str]
| Shape | Example |
|---|---|
list[str] |
["java", "python"] |
dict[str, str] |
{"py": "Python"} — surface → canonical |
dict[str, list[str]] |
{"Python": ["py", "python3"]} — canonical → surfaces |
category and priority apply to every keyword in the call.
extract(text) → list[Match]
Returns resolved matches in span order.
matches = store.extract("Patient takes aspirin daily")
extract_spans(text) → list[tuple[int, int, str]]
Fast path: (start, end, keyword_id) tuples, no Match object built. For exact +
LEFTMOST_LONGEST (the default), this skips text-slicing, attribute assignment,
and metadata handling per match — see the k=0 benchmarks above. Other
configurations still return correct results via extract() with the Match
objects stripped, just without the speed benefit.
for start, end, keyword_id in store.extract_spans("Patient takes aspirin daily"):
...
replace(text) → str
Replaces every matched span with its canonical form.
result = store.replace("take aspirin or tylenol")
Match fields
Match uses __slots__ — all fields are set at construction and the object is lightweight.
| Field | Type | Description |
|---|---|---|
text |
str |
Matched surface text as it appears in the input |
canonical |
str |
Normalised form from add_keyword |
start |
int |
Start character offset |
end |
int |
End character offset (exclusive) |
edit_distance |
int |
Levenshtein distance (0 = exact) |
category |
str | None |
User-supplied category |
priority |
float |
User-supplied priority |
keyword_id |
str |
UUID from add_keyword |
metadata |
dict |
Copy of extra kwargs |
FuzzyConfig and MatchPolicy
FuzzyConfig(max_edit_distance=1) # int, default 0
MatchPolicy |
Description |
|---|---|
ALL_OVERLAPS |
Return every match |
LEFTMOST_LONGEST |
Greedy — leftmost, then longest |
LEFTMOST_FIRST |
Greedy — leftmost, then insertion order |
HIGHEST_PRIORITY |
Greedy — highest priority wins cluster |
OPTIMAL_WEIGHTED |
Exact — maximise total priority globally |
Development
uv sync --group dev # install dependencies
python setup.py build_ext --inplace # build Cython extension
uv run pytest # run tests
uv run ruff check src tests # lint
uv run mypy src/turbotext # type-check
uv run pytest benches/ --benchmark-only # throughput benchmarks
uv run python benches/bench_1m_words.py # 1 M-word TurboText vs FlashText
uv run python benches/scaling_benchmark.py # regenerate scaling charts
Project layout
src/turbotext/
__init__.py public API exports
trie.py TrieNode + TrieBuilder
frontier.py bounded-edit frontier search (pure Python fallback)
_fast.pyx Cython hot-path for exact (k=0) and fuzzy (k>0) search
_fast.pyi type stub for the Cython extension
resolve.py conflict-resolution policies
store.py KeywordStore public class
reference/
reference_matcher.py brute-force oracle for differential testing
tests/
test_m0_smoke.py API surface + add_keywords shapes
test_m1_exact.py exact matching + boundary rules
test_m2_metadata_priorities.py metadata, HIGHEST_PRIORITY, OPTIMAL_WEIGHTED
test_m3_fuzzy.py fuzzy matching + hypothesis property tests
benches/
bench_m3.py pytest-benchmark: k=0 vs k=1 throughput
bench_comparison.py pytest-benchmark: TurboText vs FlashText vs re vs RapidFuzz
bench_1m_words.py 1 M-word throughput: TurboText vs FlashText
scaling_benchmark.py vocabulary-sweep scaling charts
assets/
logo.png
Author
Nishank Mahore
nishankmahore@gmail.com ·
github.com/nishankmahore
If TurboText is useful to you, feel free to open an issue, suggest a feature, or contribute a pull request.
License
Released under the MIT License — see LICENSE for the full text.
Made with Python · Powered by Cython · Built for speed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file turbotext-0.3.0.tar.gz.
File metadata
- Download URL: turbotext-0.3.0.tar.gz
- Upload date:
- Size: 157.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36cacb4d7bde5a91b6d2fd2856470f4ece132310437449c5224c5a5cc2462633
|
|
| MD5 |
ae8772adddbc869d2e6642c4c620db92
|
|
| BLAKE2b-256 |
75a78d75412f616216783fffaf48aa885ac3cbf69070ab7b173c0966bc5c7d35
|
File details
Details for the file turbotext-0.3.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 196.1 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3028d442279bc598775c87307aa6613fb4f85ec82043a602327af0dbf0a06198
|
|
| MD5 |
f29143496fc373cd87c18b496ee5b838
|
|
| BLAKE2b-256 |
5d941f3834ef69126ec02a8c29f2b8cd3cd87bfa3a94713c5c81cd17d69976e6
|
File details
Details for the file turbotext-0.3.0-cp313-cp313-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp313-cp313-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 509.1 kB
- Tags: CPython 3.13, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d53b49de24ee2b05fbc7645321b3f2ec0ea90f10ec8ae335a3b57442f1e75d3a
|
|
| MD5 |
d36b79cd012383167afdfaffde861f50
|
|
| BLAKE2b-256 |
113d9466c71167105c1c2d6e684a45329f94da6e2dd73311c26a368c03c17e05
|
File details
Details for the file turbotext-0.3.0-cp313-cp313-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp313-cp313-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 488.7 kB
- Tags: CPython 3.13, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d8f411bcea1302d6b4f3c4f71b7d5ef1002130a3db705b4a0c13dce7283611b
|
|
| MD5 |
326d720e9e27c221ef00590fbe78fac1
|
|
| BLAKE2b-256 |
d771ee6a9ce026a04a6b227c963fb0e2d2376932290846147084f18ac8be878d
|
File details
Details for the file turbotext-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 490.6 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f1a3699d2857fdab049d55b8e7aa8a63781848f673764a3a1b6f9aaa59cf038
|
|
| MD5 |
07429358bee64e481d650d9fff19d5d2
|
|
| BLAKE2b-256 |
2e3ca558faed7cd06505f39ad9110ab78d518d6476475f6f039d9327c8aa24a0
|
File details
Details for the file turbotext-0.3.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 493.9 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d759f30590c133e7456264536a5e62961884030c6e539cc96927b8c6406914ad
|
|
| MD5 |
e8f3c594d062000b24cab40a0907f32d
|
|
| BLAKE2b-256 |
f4cc3b80a1835ec3fb911bed1589d70669e37f4d0cbcabf1c72127e1bab4d3f7
|
File details
Details for the file turbotext-0.3.0-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 202.2 kB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59641b41f238b821386b2376a233484ac6745bc669b5c0f0741d4e9ef55405b1
|
|
| MD5 |
c1718231ecfb6005a87b352eface2fbe
|
|
| BLAKE2b-256 |
ec27e1f91f44ab62ee7136485ecc60fba214fd5ae5cfebcdc42d8aee7a102a92
|
File details
Details for the file turbotext-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl
- Upload date:
- Size: 204.6 kB
- Tags: CPython 3.13, macOS 10.13+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed2a77996554969d99d5f616a347a42659cc89abffae929861e6d31b993398c4
|
|
| MD5 |
6d499754ab3d7cdbf9ee8a73dacd2e92
|
|
| BLAKE2b-256 |
ce1c0171aca0bb0593a0ed1af8aa905630d9c286373b5dce0ff840fa13712963
|
File details
Details for the file turbotext-0.3.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 196.6 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb3e8bf8c24a021732740cbaf3f5b32e8c4c88aabe60515c43d18f32dd572dcb
|
|
| MD5 |
184800c005b6d1a5bb98dbe14e39d844
|
|
| BLAKE2b-256 |
069280f4e149a78c9e63108723c7fbbf1413226034a299e6a3e99d6f1cc04ed4
|
File details
Details for the file turbotext-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 511.5 kB
- Tags: CPython 3.12, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8aac5565305f7b27a7803f05c7f02f94bd2dd59cd3fbb4d7eaf44906264f0318
|
|
| MD5 |
e155d3797e35e2391e8e060085de92bf
|
|
| BLAKE2b-256 |
90e624413141be28f69ed676a05b3a44dc3b59f7dcd25f0b2e4c15290a78d664
|
File details
Details for the file turbotext-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 492.7 kB
- Tags: CPython 3.12, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ce3903ce5ffe64bff342b2fbb5f8b87eecee97e6b6d57bc4448de7af26b7e16
|
|
| MD5 |
b0ca5f1ea7ccdac8228cb306c60ce343
|
|
| BLAKE2b-256 |
9f43fa9921b68dc33e1d955872f5d13088d2d8532db55af39c07e957a9949e98
|
File details
Details for the file turbotext-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 496.0 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f1b980cce661cf30eecad5da628c0dc5a0d6b4f62076d0fc36a202a1349ebdb
|
|
| MD5 |
b3662a9a56da01a794ba4b6a196ae0fe
|
|
| BLAKE2b-256 |
1db44aab7b1a44ea877fceb34140a61f8b380905279fa2e6075cead372fd4350
|
File details
Details for the file turbotext-0.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 497.8 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7512d0e7b061428e40f0731b6dab287456857a04da726933439cd12c16bef8d
|
|
| MD5 |
4a5689083086cd845f4390ab8b88b49b
|
|
| BLAKE2b-256 |
e0a0044e7e5ebfa833e3dc76caead1484a0f560f709f8f9f8e0f7810d814e9f4
|
File details
Details for the file turbotext-0.3.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 202.6 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3315920f60e38c2833f78665e8f664505b62742fe6074f7642d8b3e99b1a3623
|
|
| MD5 |
24c3629c916a00497d9698b3b894d811
|
|
| BLAKE2b-256 |
9666460edd27eefaaa4c7b2f3c80e9f73ce5265cdf13f7951e1b80102f103f73
|
File details
Details for the file turbotext-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl
- Upload date:
- Size: 205.0 kB
- Tags: CPython 3.12, macOS 10.13+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce7f09f1d7e895be02ce37c0fac36a10ba446f8ea9be23a9fd4b4c56c718e94b
|
|
| MD5 |
4ee2f59fa6f96da4c9c083e3ed37e994
|
|
| BLAKE2b-256 |
0f34f71b8f80896721dbeda86785ae562663738a5f04bacc2730d3327b519aa6
|
File details
Details for the file turbotext-0.3.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 196.6 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21d26ac58737ff7c83d76c703c30f671be6c7ce7e51ca6018dcb983f9396a684
|
|
| MD5 |
f76f5ca3c607b8b135c9937309909492
|
|
| BLAKE2b-256 |
a54100a65f3a73c96a6077e3c2ccb434161d18ede09c0f30f4c3e5257b7fdc92
|
File details
Details for the file turbotext-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 529.6 kB
- Tags: CPython 3.11, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ff714c906774c0bba22ef7280dbc87f16671c980da57d7433a1c73f31671d16
|
|
| MD5 |
30b655a2984334ddcda7296b5b687cec
|
|
| BLAKE2b-256 |
8ad1d3c5f0a81aed5cac92855168c307fb1cd8fec52e59216cb2e123ef64a7fe
|
File details
Details for the file turbotext-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 513.0 kB
- Tags: CPython 3.11, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4cd5c0c351df05d20d8c3ee4b3f9e4ea9a83661328b72ebfa7a6cf2c2e92e64
|
|
| MD5 |
f9bf91a1c5582b375b239b064c1bf8ec
|
|
| BLAKE2b-256 |
8022b2c2ac523e8f45e944f53e4a0ec4ad233dadc0afd9d11984343c47f40faa
|
File details
Details for the file turbotext-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 512.0 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1dfd947313baa56f1cc1cb441e8a675493e5a3d99e491eb5962cff3b5189f2b
|
|
| MD5 |
3d77667f354e463390ad5f8ca87e3f98
|
|
| BLAKE2b-256 |
be4c0ff5d0d9a01125fbe3d9a3ee2e97a98684abbe34de48a7ba958bc7e17724
|
File details
Details for the file turbotext-0.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 511.3 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7379de7794ab9105bdd8dffaa16ffce9f01a182627b0bd315d11a3f9ef7ad89d
|
|
| MD5 |
a476fdf1a309680e1d48b81e6ab9ff2f
|
|
| BLAKE2b-256 |
09c18c463eecda4717c65a2853d654a4ef5968be141f1b492604b2c2e81c4bc7
|
File details
Details for the file turbotext-0.3.0-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 203.9 kB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a370cd0c669a59e0877e60b7105a34e16be8e77415fce94d98305a6b28f5a943
|
|
| MD5 |
5fe93b712d7215dabd419c331bbbb6df
|
|
| BLAKE2b-256 |
47aebb660901e48be505d4198adee84cdd68c87bf5fd20cbcc8c181070b674e4
|
File details
Details for the file turbotext-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl
- Upload date:
- Size: 204.0 kB
- Tags: CPython 3.11, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47b7df18c5beaa8470420367d3eed991cde8054fe6c697d094bbb3ba0e681368
|
|
| MD5 |
3aba2a464cad2b153cf5704080732578
|
|
| BLAKE2b-256 |
3b642c7c8f4d0ce39f80920d782ea869acd74dc3c575090999d34fbe14df4b1e
|
File details
Details for the file turbotext-0.3.0-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 196.6 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9268688dbf03086afe43ba21804fc2bb1019959e6ca1c3c231150d594cfc5f33
|
|
| MD5 |
be4d5ebb120698ba02fd763e071b3a7c
|
|
| BLAKE2b-256 |
5a62857cb80bf8c4219e9dc598827d87083619cff0af8893ffdb36cdd8263c76
|
File details
Details for the file turbotext-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 502.4 kB
- Tags: CPython 3.10, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
626f28bc24ab8f5f6e1dca710479d44cdca54207b951a2ae2531e8a22b8afc6f
|
|
| MD5 |
b97419900eeec8ebfe38ecfeccb048d6
|
|
| BLAKE2b-256 |
f8026f8f807d8dcabf8e8552029e5d3f0bac5833b1cfab6d4266a1f93bf6d1c0
|
File details
Details for the file turbotext-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 486.5 kB
- Tags: CPython 3.10, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
293be5c8484e1b7d355b1ea12df952640e8bbc48e540445fca16458737f9322c
|
|
| MD5 |
103a2f6fba978666c80b1555cbea34b9
|
|
| BLAKE2b-256 |
ee21be1d752b4a7b0529b47565c85960a24342551da44acf2c17cfe2cc86d628
|
File details
Details for the file turbotext-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 483.8 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb35d62a4ca2151237dd6423831c47437366b6b9fa35e6d22c453ebaa3e83aa9
|
|
| MD5 |
ae493fdc0097ad4724c45b7ac892bceb
|
|
| BLAKE2b-256 |
be6da167103a24ab59e9c7754b01ef13c3cd8382b33225249342d677691fba1a
|
File details
Details for the file turbotext-0.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 481.5 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79093c0dd5fcec4ab2baa6cf8333bad4ceb1368bbd22be54a86058425885200f
|
|
| MD5 |
1d41e58c8a0d7441acb10db9fe9257b6
|
|
| BLAKE2b-256 |
1a77b4c2074186d303bc61fd3deb7cbd9fc3cc28a7024b4909c2b1d9b22b9ec9
|
File details
Details for the file turbotext-0.3.0-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 204.0 kB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a15142e078bb93c2ea5e12b8c55633866fdac46add78f76c10c0d81346d778f7
|
|
| MD5 |
30e23976703aaee6094b08b2faccd3ed
|
|
| BLAKE2b-256 |
4cda76d331b1ff3f37dae88b63c9fff3d862f2e597fd49539212e4715cdcdd8e
|
File details
Details for the file turbotext-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl.
File metadata
- Download URL: turbotext-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl
- Upload date:
- Size: 204.2 kB
- Tags: CPython 3.10, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acbce8cca5b3ffd9a1b5f7a1a301c83be0afe4a26128b8517a0d10981668e7f6
|
|
| MD5 |
7cd3d983a3573b4f3d1577fa0404a287
|
|
| BLAKE2b-256 |
4afd78efea86ef7e31f8eed13809d2f2288d8ab7163a4ec11b90e4ccf21ab2f0
|