transcribe-cpp 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/PKG-INFO +3 -3
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/pyproject.toml +3 -3
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/src/transcribe_cpp/__init__.py +1 -1
- transcribe_cpp-0.1.2/tests/test_utf8_paths.py +87 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/.gitignore +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/LICENSE +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/README.md +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/_generate/README.md +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/_generate/check_version_sync.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/_generate/generate.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/examples/stream_wav.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/examples/transcribe_wav.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/src/transcribe_cpp/_abi.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/src/transcribe_cpp/_generated.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/src/transcribe_cpp/_library.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/src/transcribe_cpp/errors.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/src/transcribe_cpp/py.typed +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/conftest.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_abi.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_backends.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_device_select.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_errors.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_example.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_family_ext.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_lifetime.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_pcm.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_provider_discovery.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_streaming.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/tests/test_transcribe.py +0 -0
- {transcribe_cpp-0.1.0 → transcribe_cpp-0.1.2}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: transcribe-cpp
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Python bindings for transcribe.cpp
|
|
5
5
|
Project-URL: Homepage, https://github.com/handy-computer/transcribe.cpp
|
|
6
6
|
Project-URL: Repository, https://github.com/handy-computer/transcribe.cpp
|
|
@@ -21,9 +21,9 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
21
21
|
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
22
22
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
23
|
Requires-Python: >=3.9
|
|
24
|
-
Requires-Dist: transcribe-cpp-native==0.1.
|
|
24
|
+
Requires-Dist: transcribe-cpp-native==0.1.2.*
|
|
25
25
|
Provides-Extra: cu12
|
|
26
|
-
Requires-Dist: transcribe-cpp-native-cu12==0.1.
|
|
26
|
+
Requires-Dist: transcribe-cpp-native-cu12==0.1.2.*; extra == 'cu12'
|
|
27
27
|
Provides-Extra: test
|
|
28
28
|
Requires-Dist: numpy; extra == 'test'
|
|
29
29
|
Requires-Dist: pytest>=7; extra == 'test'
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "transcribe-cpp"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "Python bindings for transcribe.cpp"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# 3.8 is EOL (2024-10); 3.9 is the floor. The binding is ctypes-only, so there
|
|
@@ -34,13 +34,13 @@ classifiers = [
|
|
|
34
34
|
# packaging fix still resolves); the import-time version/header-hash check in
|
|
35
35
|
# _library.py is the runtime backstop. check_version_sync.py gates this pin
|
|
36
36
|
# against include/transcribe.h.
|
|
37
|
-
dependencies = ["transcribe-cpp-native==0.1.
|
|
37
|
+
dependencies = ["transcribe-cpp-native==0.1.2.*"]
|
|
38
38
|
|
|
39
39
|
[project.optional-dependencies]
|
|
40
40
|
# Opt-in accelerator providers — ADDITIVE: they install alongside the default
|
|
41
41
|
# provider and the best one wins at runtime. Same base-version pin contract
|
|
42
42
|
# as the hard dependency (gated by check_version_sync.py).
|
|
43
|
-
cu12 = ["transcribe-cpp-native-cu12==0.1.
|
|
43
|
+
cu12 = ["transcribe-cpp-native-cu12==0.1.2.*"]
|
|
44
44
|
# Test-only deps. Run with: uv run --extra test pytest (from bindings/python).
|
|
45
45
|
# numpy is here so the numpy PCM-input tests run in every lane instead of
|
|
46
46
|
# silently skipping wherever numpy happens to be absent.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Non-ASCII (UTF-8) path handling through the C ABI.
|
|
2
|
+
|
|
3
|
+
Regression coverage for Handy issue #1585: on Windows, model loading
|
|
4
|
+
and backend artifact-dir validation failed for non-ASCII paths because
|
|
5
|
+
the library's narrow ``::stat()`` / ``ifstream`` calls read the UTF-8
|
|
6
|
+
path bytes in the process ANSI code page. src/transcribe-path.h now
|
|
7
|
+
converts UTF-8 to wide paths on Windows.
|
|
8
|
+
|
|
9
|
+
The C++ counterpart (tests/utf8_path_unit.cpp) pins the same contract,
|
|
10
|
+
but ctest only runs on Linux/macOS in CI — this file is what executes
|
|
11
|
+
on a real Windows runner (the wheel lanes run the pytest suite via
|
|
12
|
+
scripts/ci/wheel_smoke.py).
|
|
13
|
+
|
|
14
|
+
Model-free tests always run; the full-load test skips without a model
|
|
15
|
+
(``TRANSCRIBE_SMOKE_MODEL``, set by the wheel lanes).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import os
|
|
21
|
+
import shutil
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
import pytest
|
|
25
|
+
|
|
26
|
+
import transcribe_cpp as t
|
|
27
|
+
from transcribe_cpp import errors
|
|
28
|
+
|
|
29
|
+
# Same characters as the C++ counterpart's directory name.
|
|
30
|
+
NON_ASCII_DIR = "transcribe-utf8-café-日本語"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _nonascii_dir(tmp_path: Path) -> Path:
|
|
34
|
+
d = tmp_path / NON_ASCII_DIR
|
|
35
|
+
try:
|
|
36
|
+
d.mkdir()
|
|
37
|
+
except OSError as e: # filesystem that cannot represent the name
|
|
38
|
+
pytest.skip(f"cannot create non-ASCII directory: {e}")
|
|
39
|
+
return d
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_missing_file_in_nonascii_dir_raises_file_not_found(tmp_path):
|
|
43
|
+
# The not-found classification must survive the wide-path port: a
|
|
44
|
+
# genuinely absent file is FILE_NOT_FOUND, not some generic error.
|
|
45
|
+
d = _nonascii_dir(tmp_path)
|
|
46
|
+
with pytest.raises(t.ModelFileNotFound) as ei:
|
|
47
|
+
t.Model(d / "definitely-missing.gguf")
|
|
48
|
+
assert ei.value.status == errors.ERR_FILE_NOT_FOUND
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_junk_file_in_nonascii_dir_is_found_then_rejected(tmp_path):
|
|
52
|
+
# The #1585 failure shape: the file EXISTS at the non-ASCII path,
|
|
53
|
+
# but pre-fix Windows raised ModelFileNotFound (the ANSI-code-page
|
|
54
|
+
# stat could not see it). ModelLoadError is a sibling class, so
|
|
55
|
+
# this cannot pass via FILE_NOT_FOUND.
|
|
56
|
+
d = _nonascii_dir(tmp_path)
|
|
57
|
+
junk = d / "junk.gguf"
|
|
58
|
+
junk.write_bytes(b"this is not a gguf file" * 64)
|
|
59
|
+
with pytest.raises(t.ModelLoadError):
|
|
60
|
+
t.Model(junk)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_smoke_model_loads_from_nonascii_dir(model_path, tmp_path):
|
|
64
|
+
# Full successful load through the non-ASCII path: existence
|
|
65
|
+
# pre-check, magic sniff, gguf parse, and the tensor-data streaming
|
|
66
|
+
# reopen all consume the path. Constructing the Model is the
|
|
67
|
+
# assertion.
|
|
68
|
+
d = _nonascii_dir(tmp_path)
|
|
69
|
+
local = d / model_path.name
|
|
70
|
+
shutil.copyfile(model_path, local)
|
|
71
|
+
with t.Model(local):
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_init_backends_nonascii_dirs(tmp_path):
|
|
76
|
+
# The existing non-ASCII dir must not be misread as absent;
|
|
77
|
+
# FILE_NOT_FOUND specifically is the #1585 encoding bug. We do not
|
|
78
|
+
# assert OK: a module-less dir may legitimately report ERR_BACKEND
|
|
79
|
+
# depending on build posture.
|
|
80
|
+
lib = t._lib
|
|
81
|
+
d = _nonascii_dir(tmp_path)
|
|
82
|
+
st = lib.transcribe_init_backends(os.fspath(d).encode("utf-8"))
|
|
83
|
+
assert st != errors.ERR_FILE_NOT_FOUND
|
|
84
|
+
|
|
85
|
+
missing = d / "missing-subdir"
|
|
86
|
+
st = lib.transcribe_init_backends(os.fspath(missing).encode("utf-8"))
|
|
87
|
+
assert st == errors.ERR_FILE_NOT_FOUND
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|